Skip to content

Commit fe759cb

Browse files
authored
Merge pull request #230 from DogukanUrker/feat/docker-support
feat: add docker support
2 parents 8723f45 + f68c0bb commit fe759cb

File tree

8 files changed

+926
-4
lines changed

8 files changed

+926
-4
lines changed

.dockerignore

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Exclude everything by default
2+
*
3+
4+
# Include app directory
5+
!app
6+
7+
# Exclude non-runtime files from app
8+
app/.venv
9+
app/.ruff_cache
10+
app/__pycache__
11+
app/.DS_Store
12+
app/log
13+
app/scripts

.gitignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ share/python-wheels/
2525
.installed.cfg
2626
*.egg
2727
MANIFEST
28-
uv.lock
2928

3029
# PyInstaller
3130
# Usually these files are written by a python script from a template

AGENTS.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ make help # Show all available commands
1111
make install # Install all dependencies (app + dev + test + Playwright)
1212
make install-app # Install app dependencies only
1313
make run # Run the Flask application (http://localhost:1283)
14+
make docker # Build and run with Docker
15+
make docker-build # Build Docker image
16+
make docker-run # Run Docker container
1417
make test # Run E2E tests (parallel)
1518
make test-slow # Run tests with visible browser (slow-mo, sequential)
1619
make lint # Format and lint code (auto-fix)
@@ -67,6 +70,20 @@ Translations are JSON files in `app/translations/` (en, tr, es, de, zh, fr, uk,
6770
- **Post** - id, title, content, banner (binary), author, views, category, url_id, abstract, has `hot_score` hybrid property
6871
- **Comment** - id, post_id (FK), comment, username, time_stamp
6972

73+
### Configuration
74+
75+
All settings in `app/settings.py` are read from environment variables via `os.environ.get()` with sensible defaults. A `.env` file in the project root is loaded automatically by `python-dotenv`. See `.env.example` for all available options.
76+
77+
Key settings: `APP_HOST`, `APP_PORT`, `DEBUG_MODE`, `SQLALCHEMY_DATABASE_URI`, `APP_SECRET_KEY`, `SMTP_*`, `DEFAULT_ADMIN_*`.
78+
79+
### Docker
80+
81+
- **Dockerfile** — Single-stage build using `ghcr.io/astral-sh/uv:python3.10-alpine`. Runs as non-root `flaskblog` user (UID 1000). Only production deps installed (`uv sync --frozen --no-dev --no-cache`).
82+
- **.dockerignore** — Whitelist approach: excludes everything (`*`), then includes only `app/` minus non-runtime files (`.venv`, `__pycache__`, `.ruff_cache`, `scripts`, `log`).
83+
- **Environment variables** — Not baked into the image. Passed at runtime via `docker run --env-file .env` (handled automatically by `make docker-run` if `.env` exists).
84+
- **Example DB**`app/instance/flaskblog.db` is included in the image so the app starts with sample data.
85+
- **Ports** — Container binds to `0.0.0.0:1283` (overrides Flask's default `localhost` via `APP_HOST` env var).
86+
7087
### Key Conventions
7188

7289
- Passwords hashed with Passlib's sha512_crypt

Dockerfile

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
FROM ghcr.io/astral-sh/uv:python3.14-alpine
2+
3+
RUN addgroup -g 1000 flaskblog && \
4+
adduser -u 1000 -G flaskblog -D flaskblog
5+
6+
WORKDIR /app
7+
8+
RUN chown flaskblog:flaskblog /app
9+
10+
USER flaskblog
11+
12+
COPY --chown=flaskblog:flaskblog app/pyproject.toml app/uv.lock ./
13+
14+
RUN uv sync --frozen --no-dev --no-cache && \
15+
find .venv -type d -name tests -exec rm -rf {} + 2>/dev/null; true
16+
17+
COPY --chown=flaskblog:flaskblog app/ .
18+
19+
RUN mkdir -p instance log
20+
21+
ENV PYTHONUNBUFFERED=1
22+
ENV APP_HOST=0.0.0.0
23+
ENV APP_PORT=1283
24+
25+
EXPOSE 1283
26+
27+
CMD ["uv", "run", "app.py"]

Makefile

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ UV := uv
66

77
.DEFAULT_GOAL := help
88

9-
.PHONY: help install install-app run test test-slow lint ci clean
9+
.PHONY: help install install-app run docker docker-build docker-run test test-slow lint ci clean
1010

1111
# Help
1212
help: ## Show all available commands
@@ -29,6 +29,17 @@ install-app: ## Install app dependencies only
2929
run: ## Run the Flask application (http://localhost:1283)
3030
cd $(APP_DIR) && $(UV) run app.py
3131

32+
# Docker
33+
docker: docker-build docker-run ## Build and run with Docker
34+
35+
docker-build: ## Build Docker image
36+
docker build -t flaskblog .
37+
38+
docker-run: ## Run Docker container
39+
docker run --rm -p 1283:1283 \
40+
$(if $(wildcard .env),--env-file .env) \
41+
flaskblog
42+
3243
# Testing
3344
test: ## Run E2E tests (parallel)
3445
cd $(APP_DIR) && $(UV) run pytest ../$(TESTS_DIR) -v

README.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,29 @@ make run
3737

3838
Visit `http://localhost:1283` in your browser.
3939

40+
### Docker
41+
42+
```bash
43+
make docker # Build and run with Docker
44+
```
45+
46+
Or step by step:
47+
48+
```bash
49+
make docker-build # Build the image
50+
make docker-run # Run the container
51+
```
52+
53+
### Configuration
54+
55+
All settings can be configured via environment variables. Copy the example file and modify as needed:
56+
57+
```bash
58+
cp .env.example .env
59+
```
60+
61+
See [`.env.example`](.env.example) for all available options. When using Docker, the `.env` file is automatically passed to the container.
62+
4063
### Default Admin Account
4164

4265
- Username: `admin`
@@ -59,6 +82,9 @@ make help # Show all available commands
5982
make install # Install all dependencies (app + dev + test + Playwright)
6083
make install-app # Install app dependencies only
6184
make run # Run the Flask application
85+
make docker # Build and run with Docker
86+
make docker-build # Build Docker image
87+
make docker-run # Run Docker container
6288
make test # Run E2E tests (parallel)
6389
make test-slow # Run tests with browser visible (slow-mo)
6490
make lint # Format and lint code (auto-fix)

app/utils/terminal_ascii.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ def terminal_ascii():
22
"""
33
This function returns a string containing the terminal ASCII art.
44
"""
5-
return """\033[38;2;244;63;94m
5+
return (
6+
"\033[38;2;244;63;94m"
7+
+ r"""
68
/$$$$$$$$ /$$ /$$ /$$$$$$$ /$$ /$$ /$$ /$$$$$$
79
| $$_____/| $$ | $$ | $$__ $$| $$ | $$ | $$ /$$__ $$
810
| $$ | $$ /$$$$$$ /$$$$$$$| $$ /$$| $$ \ $$| $$ /$$$$$$ /$$$$$$ | $$ | $$|__/ \ $$
@@ -15,4 +17,6 @@ def terminal_ascii():
1517
| $$$$$$/
1618
\______/
1719
by Doğukan Ürker
18-
\033[0m"""
20+
"""
21+
+ "\033[0m"
22+
)

0 commit comments

Comments
 (0)