Объявление: готовимся к обновлению программного обеспечения

Уважаемые друзья, auriz.ru готовится переехать на новую версию программного обеспечения сервиса. К сожалению, текущие записи в блоге и списках после обновления программного обеспечения не сохранятся, но, возможно, будут восстановлены позднее. Upgrade сервиса запланирован ориентировочно на 28 августа.

avm

Опубликован:  2018-02-22T07:44:20.966109Z
Отредактирован:  2018-02-22T07:04:58.064045Z
1500
Представлено пошаговое описание процесса начальной конфигурации расширяемого web-приложения на базе Debian stretch и Python3 с использованием linux-консоли, PyCharm и инструментов git. В результате выполнения описанных здесь действий будет получен git-репозиторий с кодом полноценного расширяемого web-приложения в начальной стадии разработки.

1. Необходимый набор инструментов и подготовка к проекту

Для реализации проекта Selfish на начальном этапе мне потребуется:

  • компьютер с установленной и настроенной десктопной версией Debian stretch;
  • установленный и настроенный в соответствии с этим описанием Python3;
  • установленный и настроенный PyCharm Community Edition;
  • git и активный аккаунт на github.com;
  • безлимитное соединение с сетью Интернет.

Проект Selfish - это web-приложение, дающее возможность развернуть на его базе сайт в сети Интернет или любой локальной сети, предоставляющий своим пользователям различные инструменты взаимодействия. На начальной стадии процесс разработки Selfish будет детально описан. Selfish будет базироваться на следующих составляющих:

  • MVC;
  • Python3 и web-фреймворк общего назначения Flask;
  • Jinja2 - основной шаблонизатор проекта;
  • очередь задач Сelery в связке с Redis;
  • база данных PostgreSQL и SQLAlchemy в качестве ORM;
  • jQuery и Bootstrap в клиентской части приложения.

Данное описание будет посвящено только начальной стадии разработки и продолжено в перспективе серией похожих описаний следующих стадий разработки. Целью всех этих усилий является структурный анализ и систематизация моей базы знаний, а так же выявление пробелов в ней для последующего их устранения.

2. Базовый каталог проекта

Базовый каталог проекта будет содержать все файлы проекта, необходимые для его развёртывания и полноценного функционирования. Кроме этого базовый каталог проекта будет содержать git-репозиторий и храниться на github.com.

Для создания базового каталога определяю место на жестком диске в домашнем каталоге пользователя, в моём случае это будет ~/workspace. Имя базового каталога будет совпадать с именем проекта, приведённым к нижнему регистру. Создаю базовый каталог в консоли командой mkdir.

sadmin@debian:~$ mkdir -p workspace/selfish
sadmin@debian:~$ 

Когда каталог создан, перехожу в него.

sadmin@debian:~$ cd workspace/selfish/
sadmin@debian:~/workspace/selfish$ 

Замечание: на протяжении всего процесса разработки Selfish я буду выполнять консольные команды с учётом того, что я нахожусь в его базовом каталоге ~/workspace/selfish.

3. Виртуальное окружение проекта

Виртуальное окружение - это изолированное от основной системы Python3-окружение, которое имеет собственный обособленный и независимый от основной системы набор пакетов. Виртуальное окружение является наилучшим инструментом для управления зависимостями проекта и позволяет простыми средствами перенести и развернуть проект на другую машину (например сервер).

Создаю виртуальное окружение для Selfish.

sadmin@debian:~/workspace/selfish$ python3 -m venv venv
sadmin@debian:~/workspace/selfish$ 

Команда для создания виртуального окружения содержит ключ -m venv, который указывает какой модуль стандартной библиотеки будет исполнен этой командой, далее следует имя создаваемого виртуального окружения venv, которое может быть любым, отвечающим требованиям файловой системы.

В результате выполнения этой команды в базовом каталоге появился новый каталог, содержащий созданное виртуальное окружение.

sadmin@debian:~/workspace/selfish$ ls -l
итого 4
drwxr-xr-x 6 sadmin sadmin 4096 фев 19 10:13 venv
sadmin@debian:~/workspace/selfish$ 

Далее необходимо активировать это виртуальное окружение специально предусмотренным для этого сценарием.

sadmin@debian:~/workspace/selfish$ source venv/bin/activate
(venv) sadmin@debian:~/workspace/selfish$ 

В результате активации виртуального окружения приглашение командной строки изменилось и получило соответствующий префикс, содержащий имя активного виртуального окружения.

Деактивировать виртуальное окружение можно предусмотренной для этого командой deactivate.

(venv) sadmin@debian:~/workspace/selfish$ deactivate
sadmin@debian:~/workspace/selfish$ 

Для того, чтобы виртуальное окружение и устанавливаемые в него модули правильно функционировали, мне осталось обновить wheel. Для этого, так как я деактивировал виртуальное окружение проекта, снова его активирую

sadmin@debian:~/workspace/selfish$ source venv/bin/activate
(venv) sadmin@debian:~/workspace/selfish$ 

и обновляю wheel командой pip.

(venv) sadmin@debian:~/workspace/selfish$ pip install --upgrade wheel
Collecting wheel
  Downloading wheel-0.30.0-py2.py3-none-any.whl (49kB)
    100% |████████████████████████████████| 51kB 279kB/s 
Installing collected packages: wheel
Successfully installed wheel-0.30.0
(venv) sadmin@debian:~/workspace/selfish$ 

Впоследствии, в процессе разработки Selfish его виртуальное окружение будет изменяться и дополняться, в него будут устанавливаться дополнительные модули, необходимые проекту, которые обычно называют зависимостями.

4. Создание проекта PyCharm

PyCharm - достаточно сложная и разносторонняя система, которая предоставляет ряд очень привлекательных возможностей. Чтобы использовать их, необходимо правильно завести проект Selfish в эту могучую IDE. Для этого запускаю PyCharm и оказываюсь в окне приветствия, которое предлагает создать новый проект.

pycharm-welcome

Жму соответствующую ссылку и попадаю в окно создания нового проекта, которое требует указать базовый каталог проекта и его виртуальное окружение.

pycharm-create

В строчке Location вписываю адрес базового каталога Selfish, затем в строчке Interpreter жму кнопку с шестерёнкой и в контекстном меню выбираю пункт Add local.

pycharm-venv

В модальном окне выбираю интерпретатор виртуального окружения Selfish и жму OK.

pycharm-interpreter

Убеждаюсь, что виртуальное окружение в поле Interpreter вписано верно, и создаю проект, жму Create.

pycharm-create

Подтверждаю намерение.

pycharm-proof

И оказываюсь в окне текущего проекта.

pycharm-project

Selfish стал проектом PyCharm, получил служебные файлы этой IDE в скрытом каталоге .idea, а его виртуальное окружение встроено в систему автозавершения и инспекций кода.

(venv) sadmin@debian:~/workspace/selfish$ ls -a1
.
..
.idea
venv
(venv) sadmin@debian:~/workspace/selfish$ 

С этого момента все правки кода в файлах Selfish будут сопровождаться интерактивными подсказками системы автозавершения, а все импорты и инспекции будут решаться на базе установленных в виртуальном окружении Selfish пакетов.

5. Файлы и каталоги проекта

Файлы и каталоги проекта я обычно создаю в консоли, для этого мне потребуется две консольные команды mkdir и touch. Напомню, mkdir создаёт новый каталог по указанному адресу, а touch создаёт пустой текстовый файл с указанным именем.

В рамках проекта Selfish мне нужен каталог, в котором будут храниться файлы с кодом приложения. Для этого каталога выбираю имя, совпадающее с именем проекта приведённым к нижнему регистру.

(venv) sadmin@debian:~/workspace/selfish$ mkdir selfish
(venv) sadmin@debian:~/workspace/selfish$ 

Каталог приложения является пакетом, создаю ему дандеринит.

(venv) sadmin@debian:~/workspace/selfish$ touch selfish/__init__.py
(venv) sadmin@debian:~/workspace/selfish$ 

Selfish будет иметь несколько подпрограмм, на текущем этапе проектирования создаю каталог для одной из них.

(venv) sadmin@debian:~/workspace/selfish$ mkdir selfish/main
(venv) sadmin@debian:~/workspace/selfish$ 

Даю ему свой дандеринит.

(venv) sadmin@debian:~/workspace/selfish$ touch selfish/main/__init__.py
(venv) sadmin@debian:~/workspace/selfish$ 

Ещё этой подпрограмме понадобится модуль с функциями представления этой подпрограммы.

(venv) sadmin@debian:~/workspace/selfish$ touch selfish/main/views.py
(venv) sadmin@debian:~/workspace/selfish$ 

Приложению необходим каталог для хранения шаблонов и каталог статических файлов. Создаю их.

(venv) sadmin@debian:~/workspace/selfish$ mkdir selfish/templates
(venv) sadmin@debian:~/workspace/selfish$ mkdir selfish/static
(venv) sadmin@debian:~/workspace/selfish$ 

В каталоге статических файлов определяю каталог для изображений.

(venv) sadmin@debian:~/workspace/selfish$ mkdir selfish/static/images
(venv) sadmin@debian:~/workspace/selfish$ 

Проект Selfish в перспективе будет иметь набор автоматизированных тестов, создаю для них отдельный каталог.

(venv) sadmin@debian:~/workspace/selfish$ mkdir tests
(venv) sadmin@debian:~/workspace/selfish$ 

Приложение в рамках проекта Sefish необходимо правильно сконфигурировать, для этого нужен файл конфигурации.

(venv) sadmin@debian:~/workspace/selfish$ touch config.py
(venv) sadmin@debian:~/workspace/selfish$ 

Проектом Selfish необходимо будет управлять: запускать сервер, подгружать консоль приложения, выполнять миграции для базы данных, запускать автоматизированные тесты и так далее. Для этого создаю файл для менеджера проекта.

(venv) sadmin@debian:~/workspace/selfish$ touch manage.py
(venv) sadmin@debian:~/workspace/selfish$ 

После всех трудов праведных каталог проекта приобретает следующий вид.

selfish

Это начальная структура проекта на базе Flask, далее в процессе проектирования и разработки я буду добавлять каталоги и файлы по мере необходимости.

6. Подпрограмма selfish/main

Flask - очень гибкий web-фремворк общего назначения. Приложение на базе этого фреймворка может состоять из одного файла, в то же время с его использованием можно создавать сложные многоуровневые приложения, состоящие из нескольких подпрограмм. Подпрограммы создаются на базе специального класса Blueprint и позволяют систематизировать архитектуру приложения. Selfish будет состоять из нескольких подпрограмм, первая из них selfish/main.

Для создания подпрограммы selfish/main сначала устанавливаю Flask в виртуальное окружение Selfish.

(venv) sadmin@debian:~/workspace/selfish$ pip install flask
Collecting flask
  Downloading Flask-0.12.2-py2.py3-none-any.whl (83kB)
    100% |████████████████████████████████| 92kB 371kB/s 
Collecting click>=2.0 (from flask)
  Downloading click-6.7-py2.py3-none-any.whl (71kB)
    100% |████████████████████████████████| 71kB 820kB/s 
Collecting Jinja2>=2.4 (from flask)
  Downloading Jinja2-2.10-py2.py3-none-any.whl (126kB)
    100% |████████████████████████████████| 133kB 736kB/s 
Collecting Werkzeug>=0.7 (from flask)
  Downloading Werkzeug-0.14.1-py2.py3-none-any.whl (322kB)
    100% |████████████████████████████████| 327kB 673kB/s 
Collecting itsdangerous>=0.21 (from flask)
  Downloading itsdangerous-0.24.tar.gz (46kB)
    100% |████████████████████████████████| 51kB 1.2MB/s 
Collecting MarkupSafe>=0.23 (from Jinja2>=2.4->flask)
  Downloading MarkupSafe-1.0.tar.gz
Building wheels for collected packages: itsdangerous, MarkupSafe
  Running setup.py bdist_wheel for itsdangerous ... done
  Stored in directory: /home/sadmin/.cache/pip/wheels/fc/a8/66/24d655233c757e178d45dea2de22a04c6d92766abfb741129a
  Running setup.py bdist_wheel for MarkupSafe ... done
  Stored in directory: /home/sadmin/.cache/pip/wheels/88/a7/30/e39a54a87bcbe25308fa3ca64e8ddc75d9b3e5afa21ee32d57
Successfully built itsdangerous MarkupSafe
Installing collected packages: click, MarkupSafe, Jinja2, Werkzeug, itsdangerous, flask
Successfully installed Jinja2-2.10 MarkupSafe-1.0 Werkzeug-0.14.1 click-6.7 flask-0.12.2 itsdangerous-0.24
(venv) sadmin@debian:~/workspace/selfish$ 

Затем открываю файл selfish/main/__init__.py и привожу его к следующему виду.

from flask import Blueprint

main = Blueprint('main', __name__)

from . import views

В этом файле я импортировал класс Blueprint из пакета flask, создал экземпляр этого класса - переменную main и импортировал модуль views из пакета main. Каталог selfish/main является пакетом, в дандерините пакета модули этого пакета могут быть импортированы относительным импортом посредством точки. Так как файл selfish/main/views.py уже существует, PyCharm проверил возможность импорта и выдал единственное замечание на PEP8.

pep8

К сожалению, исправить это не представляется возможным, досадно, но придётся с этим смириться. В других случаях следует стараться избегать таких замечаний и стремиться к чистоте кода.

Таким образом подпрограмма selfish/main создана, но на текущей стадии разработки пока не умеет делать ничего. Это вскоре будет исправлено. :)

7. Конфигурация экземпляра Flask

Конфигурация экземпляра Flask будет храниться в файле config.py в корне проекта Selfish. Этот файл уже создан, поэтому просто открываю его в редакторе PyCharm и привожу к следующему виду.

class Config:
    SECRET_KEY = 'My Secret Key'

    @staticmethod
    def init_app(app):
        pass


class Development(Config):
    DEBUG = True


class Testing(Config):
    TESTING = True


class Production(Config):
    pass


config = {'development': Development,
          'testing': Testing,
          'production': Production,
          'default': Development}

Здесь я определил класс Config и три класса Development, Testing и Production, которые наследуют от класса Config. Дело в том, что жизненный цикл Selfish предполагает, что приложение должно иметь несколько режимов функционирования. На стадии разработки и отладки приложение будет запускаться в режиме разработки. Автоматизированное тестирование приложения предполагает режим тестирования. И после того, как приложение наберёт необходимый функционал, оно разворачивается на сервер и работает в штатном режиме в составе сервера, исполняя заложенный в него функционал. Каждый из этих режимов может иметь характерные для него опции конфигурации. Созданные в файле config.py классы позволят дифференцировать конфигурацию приложения для каждого режима. При этом класс Config будет определять опции конфигурации общие для всех режимов запуска приложения, а его наследники будут определять опции конфигурации характерные для каждого конкретного режима работы приложения. Все предусмотренные режимы сведены в словарь config, где каждому режиму работы приложения определено название в виде строки (ключ словаря) и соответствующий класс конфигурации - значение в этом ключе. В том числе этот словарь содержит ключ default.

Кроме этого для конфигурации экземпляра Flask мне потребуется специальная программа, которая будет особым образом создавать этот экземпляр. Открываю файл selfish/__init__.py и привожу его к следующему виду.

from flask import Flask

from config import config


def create_app(config_name):
    app = Flask(__name__)
    conf_obj = config[config_name]
    app.config.from_object(conf_obj)
    conf_obj.init_app(app)
    from .main import main as main_blueprint
    app.register_blueprint(main_blueprint)
    return app

Здесь я импортировал класс Flask из пакета flask и словарь config из конфигурационного файла config.py. Далее я создал функцию create_app, которая принимает в качестве аргумента строку, содержащую название режима, в котором приложение будет запущено. Эта функция создаёт экземпляр класса Flask - приложение, производит его конфигурацию в соответствии с переданным функции аргументом, регистрирует подпрограммы и возвращает созданный экземпляр Flask.

Файл config.py и функция create_app дадут мне возможность в будущем расширять созданный экземпляр Flask, подключать в него новые модули, полученные из сторонних пакетов, создавать собственные подпрограммы, регистрировать их и управлять опциями конфигурации приложения.

selfish-init

8. Менеджер проекта

Менеджер проекта - это специальная программа, которая позволит управлять проектом в процессе разработки, отладки и тестирования приложения. Файл, в котором будет храниться код этой программы уже создан - manage.py. Менеджер проекта будет построен на основе расширения Flask-Script, которое необходимо установить в виртуальное окружение проекта.

(venv) sadmin@debian:~/workspace/selfish$ pip install Flask-Script
Collecting Flask-Script
  Downloading Flask-Script-2.0.6.tar.gz (43kB)
    100% |████████████████████████████████| 51kB 321kB/s 
Requirement already satisfied: Flask in ./venv/lib/python3.5/site-packages (from Flask-Script)
Requirement already satisfied: click>=2.0 in ./venv/lib/python3.5/site-packages (from Flask->Flask-Script)
Requirement already satisfied: itsdangerous>=0.21 in ./venv/lib/python3.5/site-packages (from Flask->Flask-Script)
Requirement already satisfied: Werkzeug>=0.7 in ./venv/lib/python3.5/site-packages (from Flask->Flask-Script)
Requirement already satisfied: Jinja2>=2.4 in ./venv/lib/python3.5/site-packages (from Flask->Flask-Script)
Requirement already satisfied: MarkupSafe>=0.23 in ./venv/lib/python3.5/site-packages (from Jinja2>=2.4->Flask->Flask-Script)
Building wheels for collected packages: Flask-Script
  Running setup.py bdist_wheel for Flask-Script ... done
  Stored in directory: /home/sadmin/.cache/pip/wheels/35/38/2a/5a4aef4aa51913c135f5d2ff6f8552ad0db06667cd3e48ef2d
Successfully built Flask-Script
Installing collected packages: Flask-Script
Successfully installed Flask-Script-2.0.6
(venv) sadmin@debian:~/workspace/selfish$ 

Открываю файл manage.py в PyCharm. Импортирую необходимые объекты из Flask-Script и Selfish.

from flask_script import Manager, Shell

from selfish import create_app

Создаю приложение при помощи функции create_app.

app = create_app('default')

Создаю экземпляр менеджера.

manager = Manager(app)

Создаю служебную функцию, формирующую набор переменных для служебной консоли проекта, на текущий момент контекст служебной консоли содержит только сконфигурированный экземпляр Flask.

def make_shell_context():
    return {'app': app}

Создаю команду менеджера для активизации служебной консоли проекта.

manager.add_command('shell', Shell(make_context=make_shell_context))

И запускаю менеджер в стандартной идиоме Питона.

if __name__ == '__main__':
    manager.run()

Таким образом файл manage.py приобретает следующий вид.

manage.py

Перехожу в консоль и тестирую программу.

(venv) sadmin@debian:~/workspace/selfish$ python manage.py --help
usage: manage.py [-?] {shell,runserver} ...

positional arguments:
  {shell,runserver}
    shell            Runs a Python shell inside Flask application context.
    runserver        Runs the Flask development server i.e. app.run()

optional arguments:
  -?, --help         show this help message and exit

Справка менеджера проекта показывает, что в настоящий момент он содержит две команды - shell и runserver. Первая (shell) запускает консоль Питона в контексте приложения (экземпляра Flask). Пробую.

(venv) sadmin@debian:~/workspace/selfish$ python manage.py shell
>>> dir()
['__builtins__', 'app']
>>> app.name
'selfish'
>>> type(app)
<class 'flask.app.Flask'>
>>> exit()
(venv) sadmin@debian:~/workspace/selfish$

Вторая команда менеджера проекта (runserver) запускает сервер, предназначенный для отладки и тестирования приложения. Работу этой команды я продемонстрирую чуть позже.

На этот момент менеджер проекта получил минимальный необходимый функционал. В процессе разработки Selfish менеджер проекта получит дополнительные полезные команды.

9. Favicon для Selfish

Поскольку Selfish в перспективе станет web-сайтом, ему понадобится иконка для избранного. Подбираю иконку на свой вкус и помещаю файл иконки в каталог selfish/static/images, этот каталог был создан ранее (см. "Файлы и каталоги проекта"). Выбранный мной файл определяется следующим образом.

(venv) sadmin@debian:~/workspace/selfish$ file selfish/static/images/*
selfish/static/images/favicon.ico: MS Windows icon resource - 1 icon, 128x128, 32 bits/pixel

Следует обратить особое внимание на имя файла - favicon.ico и на каталог, в котором этот файл хранится - selfish/static/images.

Пришло время создать первый url для Selfish. Открываю в PyCharm файл selfish/main/views.py - это модуль, который будет содержать функции представления подпрограммы selfish/main. Пишу в этот файл следующий код.

from os.path import join

from flask import current_app, request, send_from_directory

from . import main


@main.route('/favicon.ico')
def show_favicon():
    return send_from_directory(
        join(current_app.static_folder, 'images'), request.path[1:],
        mimetype='image/vnd.microsoft.icon')

Здесь я импортировал функцию join из модуля стандартной библиотеки os.path, которая поможет мне воспроизвести адрес каталога, в котором хранится файл иконки. Из пакета flask я импортировал:

  • объект current_app, с помощью которого воспроизведу адрес каталога статических файлов текущего приложения (экземпляра Flask);
  • объект request, при помощи которого получу доступ к атрибутам запроса;
  • служебную функцию send_from_directory, которая позволит получить доступ к указанному файлу иконки и сформировать HTTP ответ.

Из selfish/main я импортирую объект main, который является экземпляром класса Blueprint и позволит задать url-адреса для каждой функции представления в данном модуле. В данном случае импорт относительный посредством точки.

Далее я создаю первую функцию преставления - show_favicon, при помощи декоратора задаю этой функции представления url-адрес. В теле функции при помощи send_from_directory я формирую экземпляр класса Response и возвращаю его.

views

Теперь запускаю отладочный сервер при помощи менеджера проекта.

(venv) sadmin@debian:~/workspace/selfish$ python manage.py runserver
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
 * Restarting with stat
 * Debugger is active!
 * Debugger PIN: 109-671-440

Перехожу в web-браузер и пробую стучаться в только что созданный url.

browser

Браузер показал изображение иконки. Цель достигнута.

Замечание: отладочный сервер выдаёт в консоль важную отладочную информацию, следует обращать на неё внимание, остановить отладочный сервер можно сочетанием клавиш ctrl+c.

10. Инициализация Git

Поскольку разработка Selfish займёт определённое время и в сущности будет процессом сложным, чтобы не запутаться в коде и иметь возможность экспериментировать, мне будет нужна система контроля версий, Git - мой выбор.

В настоящий момент Selfish сконфигурирован и получил минимальный функционал, у проекта появился менеджер, приложение может быть запущено в отладочном сервере и имеет один единственный url-адрес с иконкой для избранного. Перед тем как инициировать git-репозиторий, сохраню список установленных в виртуальном окружении пакетов.

(venv) sadmin@debian:~/workspace/selfish$ pip freeze > requirements.txt
(venv) sadmin@debian:~/workspace/selfish$ 

В результате этого действия в корневом каталоге проекта появился файл requirements.txt в котором содержится список всех установленных в виртуальное окружение проекта пакетов.

(venv) sadmin@debian:~/workspace/selfish$ cat requirements.txt 
click==6.7
Flask==0.12.2
Flask-Script==2.0.6
itsdangerous==0.24
Jinja2==2.10
MarkupSafe==1.0
pkg-resources==0.0.0
Werkzeug==0.14.1
(venv) sadmin@debian:~/workspace/selfish$ 

При помощи этого файла я легко восстановлю виртуальное окружение, если это потребуется.

Далее, каталог приложения в настоящий момент содержит некоторые файлы и каталоги, которые мне не хотелось бы хранить на git-сервере. Для этого создаю файл исключений .gitignore и привожу его к следующему виду.

gitignore

Файл конфигурации умышленно попал в список исключений для git-репозитория, но потерять текущую конфигурацию никак нельзя, для этого делаю копию, из которой файл конфигурации можно будет восстановить.

(venv) sadmin@debian:~/workspace/selfish$ cp config.py config.template.py
(venv) sadmin@debian:~/workspace/selfish$ 

Делаю я так для того, чтобы иметь возможность править config.py на сервере в продакшене, и при этом не изменять содержимое git-репозитория.

Для полного счастья мне не хватает файла README.md, создаю его.

(venv) sadmin@debian:~/workspace/selfish$ echo 'http://auriz.ru/Ajnkg09' > README.md
(venv) sadmin@debian:~/workspace/selfish$

Инициирую git-репозиторий.

(venv) sadmin@debian:~/workspace/selfish$ git init .
Инициализирован пустой репозиторий Git в /home/sadmin/workspace/selfish/.git/
(venv) sadmin@debian:~/workspace/selfish$ 

При помощи команды git status можно увидеть состояние файлов в репозитории. Поскольку меня всё устраивает, добавляю файлы для первого коммита.

(venv) sadmin@debian:~/workspace/selfish$ git add .
(venv) sadmin@debian:~/workspace/selfish$ 

Теперь весь список изменений можно посмотреть.

(venv) sadmin@debian:~/workspace/selfish$ git diff --staged

Создаю первый коммит.

(venv) sadmin@debian:~/workspace/selfish$ git commit -m "Create Selfish"
[master (корневой коммит) 0a55adf] Create Selfish
 9 files changed, 84 insertions(+)
 create mode 100644 .gitignore
 create mode 100644 README.md
 create mode 100644 config.template.py
 create mode 100644 manage.py
 create mode 100644 requirements.txt
 create mode 100644 selfish/__init__.py
 create mode 100644 selfish/main/__init__.py
 create mode 100644 selfish/main/views.py
 create mode 100644 selfish/static/images/favicon.ico
(venv) sadmin@debian:~/workspace/selfish$ 

Далее я иду на github.com, создаю в своём профиле новый репозиторий с именем selfish и копирую адрес этого репозитория. Адрес выглядит так:

git@github.com:tgi-f/selfish.git

Добавляю этот адрес в свой git-репозиторий на локальной машине.

(venv) sadmin@debian:~/workspace/selfish$ git remote add origin git@github.com:tgi-f/selfish.git
(venv) sadmin@debian:~/workspace/selfish$ 

Пробую запушить свой единственный коммит на сервер.

(venv) sadmin@debian:~/workspace/selfish$ git push -u origin master
Enter passphrase for key '/home/sadmin/.ssh/id_ed25519': 
Подсчет объектов: 15, готово.
Delta compression using up to 2 threads.
Сжатие объектов: 100% (11/11), готово.
Запись объектов: 100% (15/15), 18.91 KiB | 0 bytes/s, готово.
Total 15 (delta 0), reused 0 (delta 0)
To github.com:tgi-f/selfish.git
 * [new branch]      master -> master
Ветка master отслеживает внешнюю ветку master из origin.
(venv) sadmin@debian:~/workspace/selfish$ 

Проект создан и готов к дальнейшей разработке.

Замечание: некоторые пустые каталоги пока не попали на git-сервер, это следует учитывать, тем не менее они в составе проекта и на следующих этапах разработки они появятся и на git-сервере.

11. Продолжение следует

Разработка Selfish начата. В моих планах описать начальный этап полностью вплоть до создания первых функциональных страниц. Selfish получит клиентскую часть, базу данных, очередь задач и другие интересные возможности.

В следующей серии уделю внимание клиентской части приложения, будет создан базовый шаблон и подключены необходимые для клиентской части библиотеки. На примере создания главной страницы сайта будет рассмотрена работа с html-кодом.