Skip to content

Commit 16e78a1

Browse files
postgres mvp
1 parent a32efb0 commit 16e78a1

File tree

9 files changed

+294
-0
lines changed

9 files changed

+294
-0
lines changed

sql/.gitkeep

Whitespace-only changes.

sql/postgres/.dockerignore

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
**/__pycache__
2+
**/.classpath
3+
**/.dockerignore
4+
**/.DS_Store
5+
**/.editorconfig
6+
**/.env
7+
**/.git
8+
**/.github
9+
**/.gitignore
10+
**/.project
11+
**/.settings
12+
**/.toolstarget
13+
**/.vs
14+
**/.vscode
15+
**/*.*proj.user
16+
**/*.dbmdl
17+
**/*.jfm
18+
**/*.py#
19+
**/*.py~
20+
**/*.pyc
21+
**/azds.yaml
22+
**/bin
23+
**/charts
24+
**/compose*
25+
**/csv
26+
**/django
27+
**/docker-compose*
28+
**/Dockerfile*
29+
**/img
30+
**/justfile
31+
**/Makefile
32+
**/node_modules
33+
**/npm-debug.log
34+
**/obj
35+
**/README.md
36+
**/secrets.dev.yaml
37+
**/terraform
38+
**/values.dev.yaml
39+
**/.venv

sql/postgres/.env.example

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
POSTGRES_USER=
2+
POSTGRES_PASSWORD=
3+
POSTGRES_DB=
4+
POSTGRES_HOST=
5+
POSTGRES_PORT=

sql/postgres/Dockerfile

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
# SOURCES
2+
# https://denisbrogg.hashnode.dev/efficient-python-docker-image-from-any-poetry-project
3+
# https://binx.io/2022/06/13/poetry-docker/
4+
# https://github.com/python-poetry/poetry/discussions/1879#discussioncomment-216865
5+
6+
# full semver just for python base image
7+
ARG PYTHON_VERSION=3.11.3
8+
9+
FROM python:${PYTHON_VERSION}-slim-bullseye AS builder
10+
11+
# avoid stuck build due to user prompt
12+
ARG DEBIAN_FRONTEND=noninteractive
13+
14+
# install dependencies
15+
RUN apt -qq update \
16+
&& apt -qq install \
17+
--no-install-recommends -y \
18+
curl \
19+
gcc \
20+
libpq-dev \
21+
python3-dev \
22+
&& rm -rf /var/lib/apt/lists/*
23+
24+
# pip env vars
25+
ENV PIP_NO_CACHE_DIR=off
26+
ENV PIP_DISABLE_PIP_VERSION_CHECK=on
27+
ENV PIP_DEFAULT_TIMEOUT=100
28+
29+
# path
30+
ENV VENV="/opt/venv"
31+
ENV PATH="$VENV/bin:$PATH"
32+
33+
WORKDIR /app
34+
COPY . .
35+
36+
RUN python -m venv $VENV \
37+
&& . "${VENV}/bin/activate" \
38+
&& python -m pip install -r requirements.txt
39+
40+
FROM python:${PYTHON_VERSION}-slim-bullseye AS runner
41+
42+
# setup standard non-root user for use downstream
43+
ENV USER_NAME=appuser
44+
ENV USER_GROUP=appuser
45+
ENV HOME="/home/${USER_NAME}"
46+
ENV HOSTNAME="${HOST:-localhost}"
47+
ENV VENV="/opt/venv"
48+
49+
ENV PATH="${VENV}/bin:${VENV}/lib/python${PYTHON_VERSION}/site-packages:/usr/local/bin:${HOME}/.local/bin:/bin:/usr/bin:/usr/share/doc:$PATH"
50+
51+
# standardise on locale, don't generate .pyc, enable tracebacks on seg faults
52+
ENV LANG C.UTF-8
53+
ENV LC_ALL C.UTF-8
54+
ENV PYTHONDONTWRITEBYTECODE 1
55+
ENV PYTHONFAULTHANDLER 1
56+
57+
RUN groupadd ${USER_NAME} \
58+
&& useradd -m ${USER_NAME} -g ${USER_GROUP}
59+
60+
# avoid stuck build due to user prompt
61+
ARG DEBIAN_FRONTEND=noninteractive
62+
63+
# install dependencies
64+
RUN apt -qq update \
65+
&& apt -qq install \
66+
--no-install-recommends -y \
67+
curl \
68+
lsof \
69+
&& rm -rf /var/lib/apt/lists/*
70+
71+
WORKDIR /app
72+
COPY --chown=${USER_NAME} . .
73+
COPY --from=builder --chown=${USER_NAME} "$VENV" "$VENV"
74+
75+
USER ${USER_NAME}
76+
77+
# listening port (not published)
78+
EXPOSE 8000
79+
80+
# postgres env vars
81+
ENV DATABASE_NAME=${POSTGRES_DB:-postgres}
82+
ENV DATABASE_URL=${POSTGRES_HOST:-db}
83+
ENV DATABASE_USER=${POSTGRES_USER:-postgres}
84+
ENV DATABASE_PASSWORD=${POSTGRES_PASSWORD:-mysecretpassword}
85+
ENV DATABASE_PORT=${POSTGRES_PORT:-5432}
86+
87+
ENTRYPOINT ["python", "app.py"]
88+
# CMD ["/bin/bash"]
89+
# CMD ["5000"]
90+
# CMD ["gunicorn", "-c", "gunicorn.conf.py", "main:app"]

sql/postgres/Dockerfile.postgres

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
ARG POSTGRES_VER=${POSTGRES_VER:-latest}
2+
3+
FROM postgres:${POSTGRES_VER}
4+
5+
ENV POSTGRES_USER=${POSTGRES_USER:-postgres}
6+
ENV POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-mysecretpassword}
7+
ENV POSTGRES_DB=${POSTGRES_DB:-postgres}
8+
ENV POSTGRES_HOST=${POSTGRES_HOST:-localhost}
9+
ENV POSTGRES_PORT=${POSTGRES_PORT:-5432}
10+
11+
EXPOSE ${POSTGRES_PORT}
12+
13+
# ENTRYPOINT [ "/bin/bash" ]
14+
# CMD [ "postgres", "-c", "listen_addresses='*'" ]

sql/postgres/Makefile

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
.DEFAULT_GOAL := help
2+
.ONESHELL:
3+
export SHELL := $(shell which sh)
4+
5+
# colors
6+
GREEN := $(shell tput -Txterm setaf 2)
7+
YELLOW := $(shell tput -Txterm setaf 3)
8+
WHITE := $(shell tput -Txterm setaf 7)
9+
CYAN := $(shell tput -Txterm setaf 6)
10+
RESET := $(shell tput -Txterm sgr0)
11+
12+
# targets
13+
.PHONY: all
14+
all: build pull run up stop down psql help
15+
16+
build: ## build postgres image
17+
docker build -f Dockerfile.postgress -t some-postgres:latest .
18+
19+
build-py: ## build python image
20+
docker build -f Dockerfile -t some-python:latest .
21+
22+
pull: ## pull postgres image
23+
docker pull postgres:latest
24+
25+
run: ## run postgres container
26+
docker run --rm --name some-postgres \
27+
-p 5432:5432 \
28+
-e POSTGRES_PASSWORD=mysecretpassword \
29+
-d postgres:latest
30+
31+
up: ## docker-compose
32+
docker-compose up -d
33+
34+
exec: ## docker-compose
35+
docker-compose exec -it some-python bash
36+
37+
stop: ## docker-compose
38+
docker-compose stop
39+
40+
down: ## docker-compose
41+
docker-compose down
42+
43+
psql: ## run psql
44+
docker exec -it some-postgres psql -U postgres
45+
46+
help: ## show this help
47+
@echo ''
48+
@echo 'Usage:'
49+
@echo ' ${YELLOW}make${RESET} ${GREEN}<target>${RESET}'
50+
@echo ''
51+
@echo 'Targets:'
52+
@awk 'BEGIN {FS = ":.*?## "} { \
53+
if (/^[a-zA-Z_-]+:.*?##.*$$/) {printf " ${YELLOW}%-20s${GREEN}%s${RESET}\n", $$1, $$2} \
54+
else if (/^## .*$$/) {printf " ${CYAN}%s${RESET}\n", substr($$1,4)} \
55+
}' $(MAKEFILE_LIST)

sql/postgres/app.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
#!/usr/bin/env python3
2+
3+
# SOURCE: https://towardsdatascience.com/generating-random-data-into-a-database-using-python-fd2f7d54024e
4+
5+
import os
6+
import psycopg2 as pg
7+
import pandas as pd
8+
from faker import Faker
9+
from collections import defaultdict
10+
from sqlalchemy import create_engine
11+
12+
db_name = os.getenv("DATABASE_NAME")
13+
db_host = os.getenv("DATABASE_URL")
14+
db_user = os.getenv("DATABASE_USER")
15+
db_pass = os.getenv("DATABASE_PASSWORD")
16+
db_port = os.getenv("DATABASE_PORT")
17+
18+
conn = pg.connect(database=db_name, host=db_host, user=db_user, password=db_pass, port=db_port)
19+
20+
# generate fake data
21+
fake = Faker()
22+
fake_data = defaultdict(list)
23+
24+
for _ in range(1000):
25+
fake_data["first_name"].append(fake.first_name())
26+
fake_data["last_name"].append(fake.last_name())
27+
fake_data["occupation"].append(fake.job())
28+
fake_data["dob"].append(fake.date_of_birth())
29+
fake_data["country"].append(fake.country())
30+
31+
# create dataframe
32+
df_fake_data = pd.DataFrame(fake_data)
33+
34+
# create testdb database
35+
engine = create_engine(f"postgresql://{db_user}:{db_pass}@{db_host}:{db_port}/{db_name}", echo=False)
36+
37+
# insert data into testdb database
38+
df_fake_data.to_sql("testdb", engine, if_exists="replace", index=False)
39+
40+
# read data from testdb database
41+
df_fake_data = pd.read_sql("SELECT * FROM testdb", engine)
42+
43+
44+
def main():
45+
print(df_fake_data.head())
46+
47+
48+
if __name__ == "__main__":
49+
main()

sql/postgres/docker-compose.yml

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
version: '3'
2+
3+
services:
4+
web:
5+
build: ./
6+
ports:
7+
- "80:8000"
8+
depends_on:
9+
db:
10+
condition: service_healthy
11+
# command: sh -c "sleep infinity"
12+
command: ["python", "app.py"]
13+
14+
db:
15+
image: postgres
16+
restart: unless-stopped
17+
ports:
18+
- "5432:5432"
19+
environment:
20+
POSTGRES_DB: ${POSTGRES_DB:-postgres}
21+
POSTGRES_USER: ${POSTGRES_USER:-postgres}
22+
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-mysecretpassword}
23+
healthcheck:
24+
test: ["CMD-SHELL", "pg_isready"]
25+
interval: 10s
26+
timeout: 5s
27+
retries: 5
28+
29+
adminer:
30+
image: adminer
31+
restart: unless-stopped
32+
depends_on:
33+
db:
34+
condition: service_healthy
35+
ports:
36+
- "8080:8080"

sql/postgres/requirements.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
Faker==18.7.0
2+
psycopg2-binary==2.9.6
3+
python-dateutil==2.8.2
4+
six==1.16.0
5+
SQLAlchemy==2.0.13
6+
typing_extensions==4.5.0

0 commit comments

Comments
 (0)