From cdeb87184a77d8fc5d222642449a680a54840088 Mon Sep 17 00:00:00 2001 From: finn Date: Sat, 3 Aug 2024 08:37:27 -0700 Subject: [PATCH] dockerized newsite mariadb setup --- backend/.dockerignore | 3 + backend/Dockerfile | 6 +- backend/README.md | 2 + backend/README.md.backup | 42 ------------ backend/config.py | 4 +- backend/requirements.txt | 1 + compose.yaml | 18 +++--- compose.yaml.local | 126 ++++++++++++++++++++++++++++++++++++ compose.yaml.prod | 126 ++++++++++++++++++++++++++++++++++++ proxy/{oldconf => baseconf} | 0 proxy/conf | 56 ++-------------- proxy/sslconf | 52 +++++++++++++++ 12 files changed, 332 insertions(+), 104 deletions(-) create mode 100644 backend/.dockerignore delete mode 100644 backend/README.md.backup create mode 100644 compose.yaml.local create mode 100644 compose.yaml.prod rename proxy/{oldconf => baseconf} (100%) create mode 100755 proxy/sslconf diff --git a/backend/.dockerignore b/backend/.dockerignore new file mode 100644 index 0000000..80b0b8c --- /dev/null +++ b/backend/.dockerignore @@ -0,0 +1,3 @@ +venv +migrations + diff --git a/backend/Dockerfile b/backend/Dockerfile index 36d6f5c..515a508 100755 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -1,5 +1,7 @@ # syntax=docker/dockerfile:1.4 -FROM python:3-alpine AS builder +FROM python:3-slim-bookworm AS builder + +RUN apt update && apt install -y libmariadb-dev gcc WORKDIR /code COPY requirements.txt /code @@ -9,7 +11,7 @@ RUN target=/root/.cache/pip \ # Need to make this explicit as part of expansion, no migrations or venv COPY . . -ENV FLASK_APP app.py +#ENV FLASK_APP app.py # This might be scary to leave on #ENV FLASK_ENV development diff --git a/backend/README.md b/backend/README.md index 36f57c0..4d452c0 100644 --- a/backend/README.md +++ b/backend/README.md @@ -8,6 +8,7 @@ ## pip: +mariadb may take extra work: gcc, libmariadb-dev ``` pip install flask pip install python-dotenv @@ -17,6 +18,7 @@ pip install flask-migrate pip install flask-login pip install email-validator pip install pydenticon +pip install mariadb ... pip freeze > requirements.txt ``` diff --git a/backend/README.md.backup b/backend/README.md.backup deleted file mode 100644 index 480b4e2..0000000 --- a/backend/README.md.backup +++ /dev/null @@ -1,42 +0,0 @@ -## Workflow: -- should work with flask run and dockerfile build -- local dev -- local pip install -- record versionless pips manually here -- pip freeze snapshots into project requirements -- docker build copies frozen requirements - - -## pip: -``` -pip install flask -pip install python-dotenv -pip install flask-wtf -pip install flask-sqlalchemy -pip install flask-migrate -pip install flask-login -pip install email-validator - -pip freeze > requirements.txt -``` - -## db cheat: -``` -flask db migrate -m "users table" -flask db upgrade - -flask db downgrade [base] -flask db upgrade -``` -## build: - -Dockerfile needs explicitly defined copies for: -- app -- config -- project dir -- requirements - -## notes: -- environment comes through project env passes through compose -- keep env untracked but templated -- no dotenv here, dotflaskenv goes into image diff --git a/backend/config.py b/backend/config.py index 8de6d47..8bcfc52 100644 --- a/backend/config.py +++ b/backend/config.py @@ -5,7 +5,7 @@ basedir = os.path.abspath(os.path.dirname(__file__)) class Config: SECRET_KEY = os.environ.get('FLASK_SECRET_KEY') or 'flasksk' - SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(basedir, 'zapp.db') - #SQLALCHEMY_DATABASE_URI = 'mysql://flasku:' + os.environ.get('MYSQL_PASSWORD') + '@db:3306/flask' + #SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(basedir, 'zapp.db') + SQLALCHEMY_DATABASE_URI = 'mariadb+mariadbconnector://flasku:' + os.environ.get('MYSQL_PASSWORD') + '@db:3306/flask' diff --git a/backend/requirements.txt b/backend/requirements.txt index 5020423..1576f58 100644 --- a/backend/requirements.txt +++ b/backend/requirements.txt @@ -21,3 +21,4 @@ SQLAlchemy==2.0.31 typing_extensions==4.12.2 Werkzeug==3.0.3 WTForms==3.1.2 +mariadb diff --git a/compose.yaml b/compose.yaml index 27b9454..7ceb7ff 100644 --- a/compose.yaml +++ b/compose.yaml @@ -1,12 +1,14 @@ services: db: - image: mariadb:10-focal + image: mariadb:lts restart: always healthcheck: - test: ['CMD-SHELL', 'mysqladmin ping -h 127.0.0.1 --password="${DOTENV_MYSQL_ROOT_PASSWORD}" --silent'] - interval: 3s + #test: ['CMD-SHELL', 'mysqladmin ping -h 127.0.0.1 --password="${DOTENV_MYSQL_ROOT_PASSWORD}" --silent'] + test: ['CMD', 'healthcheck.sh', '--connect', '--innodb_initialized'] + interval: 10s retries: 5 - start_period: 30s + timeout: 5s + start_period: 10s volumes: - db-data:/var/lib/mysql - ./db/init:/docker-entrypoint-initdb.d/ @@ -28,7 +30,7 @@ services: target: builder restart: always # Comment following line to use flask (1worker, dev), uncomment to use uwsgi (wsgi) - command: ["uwsgi", "--http", "0.0.0.0:8000", "--master", "-p", "4", "-w", "app:server"] + #command: ["uwsgi", "--http", "0.0.0.0:8000", "--master", "-p", "4", "-w", "app:server"] environment: - MYSQL_USER=flasku #- MYSQL_PASSWORD=flaskp @@ -86,9 +88,9 @@ services: proxy: build: proxy restart: always - volumes: - - /home/finn/d/cert/var/lib/letsencrypt:/var/lib/letsencrypt - - /home/finn/d/cert/etc/letsencrypt:/etc/letsencrypt + #volumes: + # - /home/finn/d/cert/var/lib/letsencrypt:/var/lib/letsencrypt + # - /home/finn/d/cert/etc/letsencrypt:/etc/letsencrypt ports: - 80:80 - 443:443 diff --git a/compose.yaml.local b/compose.yaml.local new file mode 100644 index 0000000..7ceb7ff --- /dev/null +++ b/compose.yaml.local @@ -0,0 +1,126 @@ +services: + db: + image: mariadb:lts + restart: always + healthcheck: + #test: ['CMD-SHELL', 'mysqladmin ping -h 127.0.0.1 --password="${DOTENV_MYSQL_ROOT_PASSWORD}" --silent'] + test: ['CMD', 'healthcheck.sh', '--connect', '--innodb_initialized'] + interval: 10s + retries: 5 + timeout: 5s + start_period: 10s + volumes: + - db-data:/var/lib/mysql + - ./db/init:/docker-entrypoint-initdb.d/ + networks: + - backnet + environment: + #- MYSQL_DATABASE=gitea + #- MYSQL_USER=gitea + #- MYSQL_PASSWORD=gitea + #- MYSQL_ROOT_PASSWORD=rootpass + - MYSQL_ROOT_PASSWORD=${DOTENV_MYSQL_ROOT_PASSWORD} + expose: + - 3306 + - 33060 + + backend: + build: + context: backend + target: builder + restart: always + # Comment following line to use flask (1worker, dev), uncomment to use uwsgi (wsgi) + #command: ["uwsgi", "--http", "0.0.0.0:8000", "--master", "-p", "4", "-w", "app:server"] + environment: + - MYSQL_USER=flasku + #- MYSQL_PASSWORD=flaskp + - MYSQL_PASSWORD=${DOTENV_MYSQL_FLASK_PASSWORD} + - TOKEN_I=${DOTENV_TOKEN_I} + - TOKEN_C=${DOTENV_TOKEN_C} + #ports: + # - 8000:8000 + expose: + - 8000 + networks: + - backnet + - frontnet + depends_on: + db: + condition: service_healthy + + gutsub: + image: gitea/gitea:latest + container_name: gitea + restart: always + environment: + - USER_UID=1000 + - USER_GID=1000 + - GITEA__database__DB_TYPE=mysql + - GITEA__database__HOST=db:3306 + - GITEA__database__NAME=gitea + - GITEA__database__USER=gitea + - GITEA__database__PASSWD=${DOTENV_MYSQL_GITEA_PASSWORD} + - GITEA__repository__DEFAULT_BRANCH=master + - GITEA__mailer__ENABLED=true + - GITEA__mailer__FROM=${GITEA_MAIL_FROM} + - GITEA__mailer__USER= + - GITEA__mailer__PROTOCOL=smtp + - GITEA__mailer__SMTP_ADDR=pmb + - GITEA__mailer__SMTP_PORT=25 + - GITEA__service__REGISTER_EMAIL_CONFIRM=true + - GITEA__service__ENABLE_NOTIFY_MAIL=true + # To disable new users after setup: + #- GITEA__service__DISABLE_REGISTRATION=false + networks: + - backnet + - frontnet + volumes: + - ./gitea:/data + - /etc/timezone:/etc/timezone:ro + - /etc/localtime:/etc/localtime:ro + #ports: + # - "3000:3000" + # - "222:22" + depends_on: + db: + condition: service_healthy + + proxy: + build: proxy + restart: always + #volumes: + # - /home/finn/d/cert/var/lib/letsencrypt:/var/lib/letsencrypt + # - /home/finn/d/cert/etc/letsencrypt:/etc/letsencrypt + ports: + - 80:80 + - 443:443 + depends_on: + - backend + networks: + - frontnet + + pmb: + #build: + # args: + # GPG_PP: $BUILD_GPG_PP + # context: pmb-pf + # dockerfile: Dockerfile + image: site_pmb:latest + expose: + - "25" + env_file: + - ./pmb-pf/.env + restart: always + volumes: + - pmb-root:/root + - /etc/localtime:/etc/localtime:ro + networks: + - backnet + +volumes: + db-data: + pmb-root: + +networks: + backnet: + frontnet: diff --git a/compose.yaml.prod b/compose.yaml.prod new file mode 100644 index 0000000..e62cf90 --- /dev/null +++ b/compose.yaml.prod @@ -0,0 +1,126 @@ +services: + db: + image: mariadb:lts + restart: always + healthcheck: + #10-focal test: ['CMD-SHELL', 'mysqladmin ping -h 127.0.0.1 --password="${DOTENV_MYSQL_ROOT_PASSWORD}" --silent'] + test: ['CMD', 'healthcheck.sh', '--connect', '--innodb_initialized'] + interval: 10s + retries: 5 + timeout: 5s + start_period: 10s + volumes: + - db-data:/var/lib/mysql + - ./db/init:/docker-entrypoint-initdb.d/ + networks: + - backnet + environment: + #- MYSQL_DATABASE=gitea + #- MYSQL_USER=gitea + #- MYSQL_PASSWORD=gitea + #- MYSQL_ROOT_PASSWORD=rootpass + - MYSQL_ROOT_PASSWORD=${DOTENV_MYSQL_ROOT_PASSWORD} + expose: + - 3306 + - 33060 + + backend: + build: + context: backend + target: builder + restart: always + # Comment following line to use flask (1worker, dev), uncomment to use uwsgi (wsgi) + command: ["uwsgi", "--http", "0.0.0.0:8000", "--master", "-p", "4", "-w", "app:server"] + environment: + - MYSQL_USER=flasku + #- MYSQL_PASSWORD=flaskp + - MYSQL_PASSWORD=${DOTENV_MYSQL_FLASK_PASSWORD} + - TOKEN_I=${DOTENV_TOKEN_I} + - TOKEN_C=${DOTENV_TOKEN_C} + #ports: + # - 8000:8000 + expose: + - 8000 + networks: + - backnet + - frontnet + depends_on: + db: + condition: service_healthy + + gutsub: + image: gitea/gitea:latest + container_name: gitea + restart: always + environment: + - USER_UID=1000 + - USER_GID=1000 + - GITEA__database__DB_TYPE=mysql + - GITEA__database__HOST=db:3306 + - GITEA__database__NAME=gitea + - GITEA__database__USER=gitea + - GITEA__database__PASSWD=${DOTENV_MYSQL_GITEA_PASSWORD} + - GITEA__repository__DEFAULT_BRANCH=master + - GITEA__mailer__ENABLED=true + - GITEA__mailer__FROM=${GITEA_MAIL_FROM} + - GITEA__mailer__USER= + - GITEA__mailer__PROTOCOL=smtp + - GITEA__mailer__SMTP_ADDR=pmb + - GITEA__mailer__SMTP_PORT=25 + - GITEA__service__REGISTER_EMAIL_CONFIRM=true + - GITEA__service__ENABLE_NOTIFY_MAIL=true + # To disable new users after setup: + #- GITEA__service__DISABLE_REGISTRATION=false + networks: + - backnet + - frontnet + volumes: + - ./gitea:/data + - /etc/timezone:/etc/timezone:ro + - /etc/localtime:/etc/localtime:ro + #ports: + # - "3000:3000" + # - "222:22" + depends_on: + db: + condition: service_healthy + + proxy: + build: proxy + restart: always + volumes: + - /home/finn/d/cert/var/lib/letsencrypt:/var/lib/letsencrypt + - /home/finn/d/cert/etc/letsencrypt:/etc/letsencrypt + ports: + - 80:80 + - 443:443 + depends_on: + - backend + networks: + - frontnet + + pmb: + #build: + # args: + # GPG_PP: $BUILD_GPG_PP + # context: pmb-pf + # dockerfile: Dockerfile + image: site_pmb:latest + expose: + - "25" + env_file: + - ./pmb-pf/.env + restart: always + volumes: + - pmb-root:/root + - /etc/localtime:/etc/localtime:ro + networks: + - backnet + +volumes: + db-data: + pmb-root: + +networks: + backnet: + frontnet: diff --git a/proxy/oldconf b/proxy/baseconf similarity index 100% rename from proxy/oldconf rename to proxy/baseconf diff --git a/proxy/conf b/proxy/conf index 80f6015..f6d2195 100755 --- a/proxy/conf +++ b/proxy/conf @@ -1,52 +1,8 @@ -#server { -# listen 80; -# server_name localhost; -# location / { -# proxy_pass http://backend:8000; -# } - - -# always redirect to https server { - listen 80 default_server; - server_name _; - return 301 https://$host$request_uri; + listen 80; + server_name localhost; + location / { + proxy_pass http://backend:8000; + } + } - -server { - listen 443 ssl http2; - # use the certificates - ssl_certificate /etc/letsencrypt/live/oily.dad/fullchain.pem; - ssl_certificate_key /etc/letsencrypt/live/oily.dad/privkey.pem; - server_name oily.dad www.oily.dad; - root /var/www/html; - index index.php index.html index.htm; - - - location / { - proxy_pass http://backend:8000/; - } -} - -server { - listen 443 ssl http2; - # use the certificates - ssl_certificate /etc/letsencrypt/live/oily.dad/fullchain.pem; - ssl_certificate_key /etc/letsencrypt/live/oily.dad/privkey.pem; - server_name gut.oily.dad; - root /var/www/html; - index index.php index.html index.htm; - - location / { - client_max_body_size 512M; - #proxy_pass http://localhost:3000; - proxy_set_header Connection $http_connection; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto $scheme; - proxy_pass http://gitea:3000/; - } -} - diff --git a/proxy/sslconf b/proxy/sslconf new file mode 100755 index 0000000..80f6015 --- /dev/null +++ b/proxy/sslconf @@ -0,0 +1,52 @@ +#server { +# listen 80; +# server_name localhost; +# location / { +# proxy_pass http://backend:8000; +# } + + +# always redirect to https +server { + listen 80 default_server; + server_name _; + return 301 https://$host$request_uri; +} + +server { + listen 443 ssl http2; + # use the certificates + ssl_certificate /etc/letsencrypt/live/oily.dad/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/oily.dad/privkey.pem; + server_name oily.dad www.oily.dad; + root /var/www/html; + index index.php index.html index.htm; + + + location / { + proxy_pass http://backend:8000/; + } +} + +server { + listen 443 ssl http2; + # use the certificates + ssl_certificate /etc/letsencrypt/live/oily.dad/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/oily.dad/privkey.pem; + server_name gut.oily.dad; + root /var/www/html; + index index.php index.html index.htm; + + location / { + client_max_body_size 512M; + #proxy_pass http://localhost:3000; + proxy_set_header Connection $http_connection; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_pass http://gitea:3000/; + } +} +