Initial commit
This commit is contained in:
+73
@@ -0,0 +1,73 @@
|
|||||||
|
# Operating system files
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
|
|
||||||
|
# Dependency directories
|
||||||
|
node_modules/
|
||||||
|
venv/
|
||||||
|
.env
|
||||||
|
*.env
|
||||||
|
|
||||||
|
# Build and output folders
|
||||||
|
dist/
|
||||||
|
build/
|
||||||
|
out/
|
||||||
|
coverage/
|
||||||
|
coverage-final.json
|
||||||
|
|
||||||
|
# Logs
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
pnpm-debug.log*
|
||||||
|
*.log
|
||||||
|
|
||||||
|
# Temporary files
|
||||||
|
tmp/
|
||||||
|
temp/
|
||||||
|
*.tmp
|
||||||
|
*.swp
|
||||||
|
*.swo
|
||||||
|
|
||||||
|
# IDE/editor directories
|
||||||
|
.vscode/
|
||||||
|
.idea/
|
||||||
|
*.sublime-workspace
|
||||||
|
*.sublime-project
|
||||||
|
|
||||||
|
# API/Web project specific
|
||||||
|
.env.local
|
||||||
|
.env.*.local
|
||||||
|
/.next/
|
||||||
|
/.nuxt/
|
||||||
|
/.vercel/
|
||||||
|
/.cache/
|
||||||
|
|
||||||
|
# Compiled files
|
||||||
|
*.class
|
||||||
|
*.dll
|
||||||
|
*.exe
|
||||||
|
*.o
|
||||||
|
*.pyc
|
||||||
|
*.pyo
|
||||||
|
*.pyd
|
||||||
|
__pycache__/
|
||||||
|
|
||||||
|
# Misc
|
||||||
|
.DS_Store
|
||||||
|
*.bak
|
||||||
|
*.backup
|
||||||
|
*.orig
|
||||||
|
*.rej
|
||||||
|
|
||||||
|
# Ignore secrets and credentials
|
||||||
|
secret*
|
||||||
|
credentials*
|
||||||
|
|
||||||
|
# Generated documentation
|
||||||
|
doc/api/
|
||||||
|
docs/
|
||||||
|
|
||||||
|
# Docker
|
||||||
|
docker-compose.override.yml
|
||||||
|
*.log
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
.PHONY: help
|
||||||
|
|
||||||
|
dc = docker compose
|
||||||
|
devDC = $(dc) -f compose.yaml -f compose.dev.yaml
|
||||||
|
project = dc
|
||||||
|
|
||||||
|
help:
|
||||||
|
@echo "Usage: <command> \n"
|
||||||
|
@echo "- prod"
|
||||||
|
@echo "- dev"
|
||||||
|
@echo "- down"
|
||||||
|
@echo "- log"
|
||||||
|
@echo "- config"
|
||||||
|
@echo "- devConfig"
|
||||||
|
|
||||||
|
prod:
|
||||||
|
$(dc) up -d
|
||||||
|
|
||||||
|
dev:
|
||||||
|
$(devDC) up -d
|
||||||
|
|
||||||
|
down:
|
||||||
|
$(devDC) down
|
||||||
|
|
||||||
|
logs:
|
||||||
|
$(devDC) logs -f --tail=20
|
||||||
|
|
||||||
|
config:
|
||||||
|
$(devDC) config
|
||||||
|
|
||||||
|
devConfig:
|
||||||
|
$(devDC) config
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
# ProjectName
|
||||||
|
|
||||||
|
ProjectName — это проект для организации задач команды и управления рабочими процессами.
|
||||||
|
|
||||||
|
Этот репозиторий `deploy` служит оркестратором проекта.
|
||||||
|
Он содержит инфраструктуру и конфигурации для развёртывания ProjectName, управления окружениями и запуска служб.
|
||||||
|
|
||||||
|
Основные задачи репозитория `deploy`:
|
||||||
|
- подготовка инфраструктуры для приложения;
|
||||||
|
- настройка CI/CD и автоматического деплоя;
|
||||||
|
- управление конфигурациями окружений;
|
||||||
|
- запуск и мониторинг сервисов.
|
||||||
|
|
||||||
|
Использование:
|
||||||
|
1. Настройте переменные окружения и секреты.
|
||||||
|
2. Запустите процедуры развёртывания.
|
||||||
|
3. Следите за состоянием сервиса и логами.
|
||||||
|
|
||||||
|
Этот репозиторий не содержит основную логику приложения ProjectName, а отвечает за его развёртывание и эксплуатацию.
|
||||||
+91
@@ -0,0 +1,91 @@
|
|||||||
|
# git-cliff ~ default configuration file
|
||||||
|
# https://git-cliff.org/docs/configuration
|
||||||
|
#
|
||||||
|
# Lines starting with "#" are comments.
|
||||||
|
# Configuration options are organized into tables and keys.
|
||||||
|
# See documentation for more information on available options.
|
||||||
|
|
||||||
|
[changelog]
|
||||||
|
# changelog header
|
||||||
|
header = """
|
||||||
|
# Changelog\n
|
||||||
|
All notable changes to this project will be documented in this file.\n
|
||||||
|
"""
|
||||||
|
# template for the changelog body
|
||||||
|
# https://keats.github.io/tera/docs/#introduction
|
||||||
|
body = """
|
||||||
|
{% if version %}\
|
||||||
|
## [{{ version | trim_start_matches(pat="v") }}] - {{ timestamp | date(format="%Y-%m-%d") }}
|
||||||
|
{% else %}\
|
||||||
|
## [unreleased]
|
||||||
|
{% endif %}\
|
||||||
|
{% for group, commits in commits | group_by(attribute="group") %}
|
||||||
|
### {{ group | striptags | trim | upper_first }}
|
||||||
|
{% for commit in commits %}
|
||||||
|
- {% if commit.scope %}*({{ commit.scope }})* {% endif %}\
|
||||||
|
{% if commit.breaking %}[**breaking**] {% endif %}\
|
||||||
|
{{ commit.message | upper_first }}\
|
||||||
|
{% endfor %}
|
||||||
|
{% endfor %}\n
|
||||||
|
"""
|
||||||
|
# template for the changelog footer
|
||||||
|
footer = """
|
||||||
|
<!-- generated by git-cliff -->
|
||||||
|
"""
|
||||||
|
# remove the leading and trailing s
|
||||||
|
trim = true
|
||||||
|
# postprocessors
|
||||||
|
postprocessors = [
|
||||||
|
{ pattern = '(IDA-\d+)', replace = "[${1}](https://ru.yougile.com/team/a0c003776084/Identity#${1})" }
|
||||||
|
# { pattern = '<REPO>', replace = "https://github.com/orhun/git-cliff" }, # replace repository URL
|
||||||
|
]
|
||||||
|
|
||||||
|
[git]
|
||||||
|
# parse the commits based on https://www.conventionalcommits.org
|
||||||
|
conventional_commits = true
|
||||||
|
# filter out the commits that are not conventional
|
||||||
|
filter_unconventional = true
|
||||||
|
# process each line of a commit as an individual commit
|
||||||
|
split_commits = false
|
||||||
|
# regex for preprocessing the commit messages
|
||||||
|
commit_preprocessors = [
|
||||||
|
# Replace issue numbers
|
||||||
|
#{ pattern = '\((\w+\s)?#([0-9]+)\)', replace = "([#${2}](<REPO>/issues/${2}))"},
|
||||||
|
# Check spelling of the commit with https://github.com/crate-ci/typos
|
||||||
|
# If the spelling is incorrect, it will be automatically fixed.
|
||||||
|
#{ pattern = '.*', replace_command = 'typos --write-changes -' },
|
||||||
|
]
|
||||||
|
# regex for parsing and grouping commits
|
||||||
|
commit_parsers = [
|
||||||
|
{ message = "^feat", group = "<!-- 0 -->🚀 Features" },
|
||||||
|
{ message = "^fix", group = "<!-- 1 -->🐛 Bug Fixes" },
|
||||||
|
{ message = "^fixes", group = "<!-- 10 -->🐛 Fixes" },
|
||||||
|
{ message = "^doc", group = "<!-- 3 -->📚 Documentation" },
|
||||||
|
{ message = "^perf", group = "<!-- 4 -->⚡ Performance" },
|
||||||
|
{ message = "^refactor", group = "<!-- 2 -->🚜 Refactor" },
|
||||||
|
{ message = "^style", group = "<!-- 5 -->🎨 Styling" },
|
||||||
|
{ message = "^test", group = "<!-- 6 -->🧪 Testing" },
|
||||||
|
{ message = "^chore\\(release\\): prepare for", skip = true },
|
||||||
|
{ message = "^chore\\(deps.*\\)", skip = true },
|
||||||
|
{ message = "^chore\\(pr\\)", skip = true },
|
||||||
|
{ message = "^chore\\(pull\\)", skip = true },
|
||||||
|
{ message = "^chore|^ci", group = "<!-- 7 -->⚙️ Miscellaneous Tasks" },
|
||||||
|
{ body = ".*security", group = "<!-- 8 -->🛡️ Security" },
|
||||||
|
{ message = "^revert", group = "<!-- 9 -->◀️ Revert" },
|
||||||
|
]
|
||||||
|
# protect breaking changes from being skipped due to matching a skipping commit_parser
|
||||||
|
protect_breaking_commits = false
|
||||||
|
# filter out the commits that are not matched by commit parsers
|
||||||
|
filter_commits = false
|
||||||
|
# regex for matching git tags
|
||||||
|
# tag_pattern = "v[0-9].*"
|
||||||
|
# regex for skipping tags
|
||||||
|
# skip_tags = ""
|
||||||
|
# regex for ignoring tags
|
||||||
|
# ignore_tags = ""
|
||||||
|
# sort the tags topologically
|
||||||
|
topo_order = false
|
||||||
|
# sort the commits inside sections by oldest/newest order
|
||||||
|
sort_commits = "oldest"
|
||||||
|
# limit the number of commits included in the changelog.
|
||||||
|
# limit_commits = 42
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
services:
|
||||||
|
|
||||||
|
adminer:
|
||||||
|
container_name: ${APP_PREFIX}-${APP_ENV}-adminer
|
||||||
|
image: adminer:${DEPLOY_ADMINER_TAG:-5.4.2-standalone}
|
||||||
|
restart: always
|
||||||
|
environment:
|
||||||
|
ADMINER_PLUGINS: >
|
||||||
|
tables-filter tinymce dump-json table-structure pretty-json-column
|
||||||
|
dark-switcher idsmk-edit-foreign
|
||||||
|
ADMINER_DESIGN: dracula
|
||||||
|
ADMINER_DEFAULT_SERVER: db
|
||||||
|
links:
|
||||||
|
- "db"
|
||||||
|
depends_on:
|
||||||
|
db:
|
||||||
|
condition: service_healthy
|
||||||
|
volumes:
|
||||||
|
- ./services/adminer/idsmk-edit-foreign.php:/var/www/html/plugins/idsmk-edit-foreign.php:ro
|
||||||
|
- /etc/localtime:/etc/localtime:ro
|
||||||
|
networks:
|
||||||
|
net:
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
services:
|
||||||
|
nginx:
|
||||||
|
container_name: ${APP_PREFIX}-${APP_ENV}-nginx
|
||||||
|
image: nginx:${DEPLOY_NGINX_TAG:-1.29.8-alpine-slim}
|
||||||
|
restart: always
|
||||||
|
working_dir: /etc/nginx/conf.d
|
||||||
|
env_file:
|
||||||
|
- .env
|
||||||
|
ports:
|
||||||
|
- "${APP_PORT}:80"
|
||||||
|
# depends_on:
|
||||||
|
# api:
|
||||||
|
# condition: service_started
|
||||||
|
healthcheck:
|
||||||
|
test: wget --no-verbose --tries=1 --spider http://localhost || exit 1
|
||||||
|
interval: 5m
|
||||||
|
timeout: 3s
|
||||||
|
retries: 3
|
||||||
|
start_period: 2m
|
||||||
|
volumes:
|
||||||
|
- ./services/nginx/hosts/${NGINX_HOSTS}:/etc/nginx/templates
|
||||||
|
- ./services/nginx/.htpasswd:/etc/nginx/.htpasswd
|
||||||
|
- /etc/localtime:/etc/localtime:ro
|
||||||
|
networks:
|
||||||
|
net:
|
||||||
|
|
||||||
|
db:
|
||||||
|
container_name: ${APP_PREFIX}-${APP_ENV}-db
|
||||||
|
image: postgres:${DEPLOY_POSTGRES_TAG:-18.3-alpine3.23}
|
||||||
|
restart: always
|
||||||
|
environment:
|
||||||
|
POSTGRES_USER: ${DB_USERNAME}
|
||||||
|
POSTGRES_PASSWORD: ${DB_PASSWORD}
|
||||||
|
POSTGRES_DATABASE: ${DB_DATABASE}
|
||||||
|
healthcheck:
|
||||||
|
test: [ "CMD-SHELL", "pg_isready -U ${DB_USERNAME} -d ${DB_DATABASE}" ]
|
||||||
|
interval: 5s
|
||||||
|
timeout: 2s
|
||||||
|
retries: 5
|
||||||
|
volumes:
|
||||||
|
- db:/var/lib/postgresql
|
||||||
|
- /etc/localtime:/etc/localtime:ro
|
||||||
|
networks:
|
||||||
|
net:
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
db:
|
||||||
|
name: ${APP_PREFIX}-${APP_ENV}-db
|
||||||
|
|
||||||
|
networks:
|
||||||
|
net:
|
||||||
|
name: ${APP_PREFIX}-${APP_ENV}-net
|
||||||
@@ -0,0 +1,92 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Select foreign key in edit form
|
||||||
|
* @link https://www.adminer.org/plugins/#use
|
||||||
|
* @author WiRight, IDSMK
|
||||||
|
* @license https://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
|
||||||
|
* @license https://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other)
|
||||||
|
*/
|
||||||
|
class AdminerIDSMKEditForeign extends Adminer\Plugin {
|
||||||
|
protected $limit;
|
||||||
|
|
||||||
|
function __construct($limit = 0) {
|
||||||
|
$this->limit = $limit;
|
||||||
|
}
|
||||||
|
|
||||||
|
function editInput($table, $field, $attrs, $value) {
|
||||||
|
static $foreignTables = [];
|
||||||
|
static $values = [];
|
||||||
|
|
||||||
|
$foreignKeys = &$foreignTables[$table];
|
||||||
|
|
||||||
|
if ($foreignKeys === null) {
|
||||||
|
$foreignKeys = Adminer\column_foreign_keys($table);
|
||||||
|
}
|
||||||
|
|
||||||
|
$titleFields = [
|
||||||
|
'name',
|
||||||
|
'title',
|
||||||
|
'nickname',
|
||||||
|
'email',
|
||||||
|
];
|
||||||
|
|
||||||
|
$titleFieldName = null;
|
||||||
|
|
||||||
|
foreach ((array) $foreignKeys[$field["field"]] as $foreignKey) {
|
||||||
|
if (count($foreignKey["source"]) == 1) {
|
||||||
|
$target = $foreignKey["table"];
|
||||||
|
$id = $foreignKey["target"][0];
|
||||||
|
$options = &$values[$target][$id];
|
||||||
|
|
||||||
|
if (!$options) {
|
||||||
|
$column = Adminer\idf_escape($id);
|
||||||
|
|
||||||
|
if (preg_match('~binary~', $field["type"])) {
|
||||||
|
$column = "HEX($column)";
|
||||||
|
}
|
||||||
|
|
||||||
|
$selectFields = [
|
||||||
|
$column,
|
||||||
|
];
|
||||||
|
|
||||||
|
$targetFields = array_keys(Adminer\fields($target));
|
||||||
|
|
||||||
|
foreach ($targetFields as $targetField) {
|
||||||
|
if (in_array($targetField, $titleFields)) {
|
||||||
|
$selectFields[] = Adminer\idf_escape($targetField);
|
||||||
|
$titleFieldName = $targetField;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$rows = Adminer\get_rows('SELECT ' . implode(',', $selectFields) . ' FROM ' . Adminer\table($target) . ' ORDER BY 1');
|
||||||
|
|
||||||
|
$options = [
|
||||||
|
'',
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($rows as $row) {
|
||||||
|
$options[$row[$id]] = $row[$titleFieldName ?? $id];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->limit && count($options) - 1 > $this->limit) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return "<select$attrs>" . Adminer\optionlist($options, $value, true) . "</select>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected $translations = [
|
||||||
|
'cs' => ['' => 'Výběr cizího klíče v editačním formuláři'],
|
||||||
|
'de' => ['' => 'Wählen Sie im Bearbeitungsformular den Fremdschlüssel aus'],
|
||||||
|
'pl' => ['' => 'Wybierz klucz obcy w formularzu edycji'],
|
||||||
|
'ro' => ['' => 'Selectați cheia străină în formularul de editare'],
|
||||||
|
'ja' => ['' => '外部キーを編集フォームで選択'],
|
||||||
|
'ru' => ['' => 'Выбор внешнего ключа при редактировании таблицы (с подстановкой Title)'],
|
||||||
|
];
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
asmkuser:$apr1$95jzw9DR$qCcDTA8jp2tges/mk8Hyg1
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
|
||||||
|
server_name adminer.${APP_HOST};
|
||||||
|
|
||||||
|
client_max_body_size 50M;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
|
||||||
|
proxy_pass http://adminer:8080;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
|
||||||
|
server_name api.${APP_HOST};
|
||||||
|
|
||||||
|
client_max_body_size 500m;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_buffering off;
|
||||||
|
proxy_cache off;
|
||||||
|
proxy_read_timeout 86400s;
|
||||||
|
chunked_transfer_encoding on;
|
||||||
|
|
||||||
|
proxy_pass http://api:8080;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
server {
|
||||||
|
listen 80 default_server;
|
||||||
|
|
||||||
|
server_name ${APP_HOST};
|
||||||
|
|
||||||
|
client_max_body_size 500m;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
|
||||||
|
proxy_pass http://web:3000;
|
||||||
|
}
|
||||||
|
|
||||||
|
location /_nuxt/ {
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection "upgrade";
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
|
||||||
|
proxy_cache_bypass $http_upgrade;
|
||||||
|
|
||||||
|
proxy_pass http://web:3000;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
|
||||||
|
server_name api.${APP_HOST};
|
||||||
|
|
||||||
|
client_max_body_size 500m;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
|
||||||
|
proxy_pass http://api:8080;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
server {
|
||||||
|
listen 80 default_server;
|
||||||
|
|
||||||
|
server_name ${APP_HOST};
|
||||||
|
|
||||||
|
client_max_body_size 500m;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
|
||||||
|
proxy_pass http://web:3000;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
*
|
||||||
|
!.gitignore
|
||||||
Reference in New Issue
Block a user