2021-12-11 / Bartłomiej Kurek
Django - virtual mail manager (#1 - setup)

W ramach migracji na nowy serwer postanowiłem uporządkować część wdrożeń. Jednym z nich jest system pocztowy oparty o postfix (smtp), dovecot2 (imap), bazę danych sqlite3.
W tej serii artykułów omówimy tworzenie prostej aplikacji w Django, która będzie umożliwiać zarządzanie kontami email w ramach tego systemu.

Zarys aplikacji

Aplikację nazwę "vmapp" (virtual mail application).
Celem jest stworzenie prostej aplikacji Django i jej testów jednostkowych.
Docelowo aplikacja będzie wdrożona jako kontener docker (przy użyciu docker-compose). Dane będą przechowywane w bazie danych sqlite3, a jej schemat obejmie jedynie 3 tabele: users, domains, aliases.

W tabeli users przechowywane są rekordy kont email, na które składają się pola:
- user_id
- username
- domain
- password
- quota
- is_enabled
- ctime
- mtime

Tabela domains zawierać będzie jedynie pola:
- domain_id
- domain
- is_enabled
- ctime
- mtime

W tabeli aliases znajdą się rekordy przekierowań adresów email na konkretną skrzynkę pocztową. Rekordy te zawierać będą jedynie:
- alias_id
- email
- alias
- is_enabled
- ctime
- mtime

Przygotowanie projektu

Python

Tworzę katalog vmapp i przechodzę do niego:

$ mkdir vmapp
$ cd vmapp

Następnie tworzę i aktywuję wirtualne środowisko python w katalogu ".venv".

$ python3 -m venv .venv
$ . .venv/bin/activate

Teraz instaluję Django:

$ pip install Django
Collecting Django
  Downloading Django-4.0-py3-none-any.whl (8.0 MB)
     |████████████████████████████████| 8.0 MB 5.8 MB/s 
  ...

Zainstalowana wersja Django to 4.0. Tworzę zatem plik requirements.txt:

$ pip freeze | grep -i django > requirements.txt
$ cat requirements.txt 
Django==4.0

Teraz instalacja zależności będzie sprowadzać się do komendy:

$ pip install -r requirements.txt
Requirement already satisfied: Django==4.0 in ...

Git

Na tym etapie od razu inicjalizuję repozytorium git.

$ git init .
Initialized empty Git repository ...

Ustawiam w tym repozytorium nazwę użytkownika, oraz email:

$ git config user.name CodeASAP.pl
$ git config user.email "95665514+codeasap-pl@users.noreply.github.com"

Tworzę plik .gitignore:

$ cat > .gitignore
.venv/
__pycache__/
.ignore/
.secure/
*#*
*.bak

Tworzę plik README.md:

$ echo "# Virtual mail manager" > README.md

Dodaję obecne pliki do repozytorium:

$ git add .gitignore README.md requirements.txt

$ git status -s
A  .gitignore
A  README.md
A  requirements.txt

$ git commit -m "Init" 
[master (root-commit) 9a9f328] Init
 3 files changed, 8 insertions(+)
 create mode 100644 .gitignore
 create mode 100644 README.md
 create mode 100644 requirements.txt

$ git status
On branch master
nothing to commit, working tree clean

Na koniec tworzę osobną gałąź devel, w której będę rozwijał kod. Przetestowany kod będzie później trafiał (merge) do głównej gałęzi "master".

$ git checkout -b devel
Switched to a new branch 'devel'

$ git branch
* devel
  master

Stworzenie aplikacji Django

Tworzę aplikację przy użyciu django-admin.

django-admin startproject vmapp

Komenda ta tworzy szkielet aplikacji (katalog "vmapp" i strukturę katalogów i plików):

$ tree vmapp/
vmapp/
├── manage.py
└── vmapp
    ├── asgi.py
    ├── __init__.py
    ├── settings.py
    ├── urls.py
    └── wsgi.py

Dodanie kodu do repozytorium lokalnego

Dodaję to wszystko do repozytorium git.

$ git add vmapp
$ git commit -m "Django skeleton app"
[devel a0b2c87] Django skeleton app
 6 files changed, 198 insertions(+)
 create mode 100755 vmapp/manage.py
 create mode 100644 vmapp/vmapp/__init__.py
 create mode 100644 vmapp/vmapp/asgi.py
 create mode 100644 vmapp/vmapp/settings.py
 create mode 100644 vmapp/vmapp/urls.py
 create mode 100644 vmapp/vmapp/wsgi.py

Licencja

Na koniec umieszczam również plik licencji (LICENSE) kodu.

$ head -4 LICENSE 
MIT License

Copyright (c) 2021 CodeASAP.pl
$ git add LICENSE 
$ git commit -m "License" LICENSE 
[devel 9096cdc] License
 1 file changed, 21 insertions(+)
 create mode 100644 LICENSE

Kod szkieletu aplikacji oraz licencji znajdują się w gałęzi devel, a zatem wykonam merge: devel -> master.

$ git checkout master
Switched to branch 'master'

$ git merge devel
Updating 9a9f328..9096cdc
Fast-forward
 LICENSE                 |  21 +++++++++++++++++++++
 vmapp/manage.py         |  22 ++++++++++++++++++++++
 vmapp/vmapp/__init__.py |   0
 vmapp/vmapp/asgi.py     |  16 ++++++++++++++++
 vmapp/vmapp/settings.py | 123 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 vmapp/vmapp/urls.py     |  21 +++++++++++++++++++++
 vmapp/vmapp/wsgi.py     |  16 ++++++++++++++++
 7 files changed, 219 insertions(+)
 create mode 100644 LICENSE
 create mode 100755 vmapp/manage.py
 create mode 100644 vmapp/vmapp/__init__.py
 create mode 100644 vmapp/vmapp/asgi.py
 create mode 100644 vmapp/vmapp/settings.py
 create mode 100644 vmapp/vmapp/urls.py
 create mode 100644 vmapp/vmapp/wsgi.py

Repozytorium GitHub

Całość wgrywam do repozytorium utworzonego na platformie GitHub.

$ git remote add origin git@github.com:codeasap-pl/vmapp.git

$ git remote -v
origin  git@github.com:codeasap-pl/vmapp.git (fetch)
origin  git@github.com:codeasap-pl/vmapp.git (push)

$ git push --set-upstream origin master
Enter passphrase for key '/home/me/.ssh/codeasap-github': 
Enumerating objects: 18, done.
Counting objects: 100% (18/18), done.
Delta compression using up to 4 threads
Compressing objects: 100% (14/14), done.
Writing objects: 100% (18/18), 3.95 KiB | 1.32 MiB/s, done.
Total 18 (delta 4), reused 0 (delta 0), pack-reused 0
remote: Resolving deltas: 100% (4/4), done.
To github.com:codeasap-pl/vmapp.git
 * [new branch]      master -> master
Branch 'master' set up to track remote branch 'master' from 'origin'.

Repozytorium widnieje już w GitHub.
img-border

W następnej części zajmiemy się uruchomieniem panelu administracyjnego Django.