sqlite
This commit is contained in:
+3
-8
@@ -7,19 +7,14 @@ APP_URL=https://example.ru
|
|||||||
LOG_CHANNEL=stderr
|
LOG_CHANNEL=stderr
|
||||||
LOG_LEVEL=error
|
LOG_LEVEL=error
|
||||||
|
|
||||||
DB_CONNECTION=mysql
|
DB_CONNECTION=sqlite
|
||||||
DB_HOST=mysql
|
DB_DATABASE=/var/www/html/database/sqlite/database.sqlite
|
||||||
DB_PORT=3306
|
|
||||||
DB_DATABASE=airservice
|
|
||||||
DB_USERNAME=airservice
|
|
||||||
DB_PASSWORD=
|
|
||||||
DB_ROOT_PASSWORD=
|
|
||||||
|
|
||||||
BROADCAST_DRIVER=log
|
BROADCAST_DRIVER=log
|
||||||
CACHE_DRIVER=file
|
CACHE_DRIVER=file
|
||||||
FILESYSTEM_DISK=local
|
FILESYSTEM_DISK=local
|
||||||
QUEUE_CONNECTION=database
|
QUEUE_CONNECTION=database
|
||||||
SESSION_DRIVER=database
|
SESSION_DRIVER=file
|
||||||
SESSION_LIFETIME=120
|
SESSION_LIFETIME=120
|
||||||
|
|
||||||
# S3 (опционально, если нужно хранение файлов)
|
# S3 (опционально, если нужно хранение файлов)
|
||||||
|
|||||||
+3
-3
@@ -11,11 +11,11 @@ FROM php:8.2-fpm-alpine AS app
|
|||||||
WORKDIR /var/www/html
|
WORKDIR /var/www/html
|
||||||
|
|
||||||
RUN apk add --no-cache \
|
RUN apk add --no-cache \
|
||||||
libpng-dev libjpeg-turbo-dev freetype-dev libzip-dev \
|
libpng-dev libjpeg-turbo-dev freetype-dev libzip-dev sqlite \
|
||||||
zip unzip git mysql-client
|
zip unzip git
|
||||||
|
|
||||||
RUN docker-php-ext-configure gd --with-freetype --with-jpeg \
|
RUN docker-php-ext-configure gd --with-freetype --with-jpeg \
|
||||||
&& docker-php-ext-install pdo pdo_mysql gd zip opcache pcntl
|
&& docker-php-ext-install pdo pdo_sqlite gd zip opcache pcntl
|
||||||
|
|
||||||
COPY --from=composer:2 /usr/bin/composer /usr/bin/composer
|
COPY --from=composer:2 /usr/bin/composer /usr/bin/composer
|
||||||
|
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
# AirService
|
# AirService
|
||||||
|
|
||||||
Система управления заявками на техническое обслуживание (Service Desk). Сотрудники создают заявки, назначают приоритеты и отслеживают статус выполнения.
|
Система управления заявками на техническое обслуживание (Service Desk).
|
||||||
|
|
||||||
**Стек:** Laravel 10, Livewire, Tailwind CSS, MySQL, Vite
|
**Стек:** Laravel 10, Livewire, Tailwind CSS, SQLite, Vite
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Локальная разработка
|
## Локальная разработка
|
||||||
|
|
||||||
**Требования:** PHP >= 8.2, Composer, Node.js >= 18, MySQL
|
**Требования:** PHP >= 8.2, Composer, Node.js >= 18
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git clone <repo-url>
|
git clone <repo-url>
|
||||||
@@ -18,9 +18,10 @@ composer install
|
|||||||
npm install
|
npm install
|
||||||
|
|
||||||
cp .env.example .env
|
cp .env.example .env
|
||||||
# Поменять APP_ENV=local, APP_DEBUG=true, APP_URL=http://localhost
|
# Поменять APP_ENV=local, APP_DEBUG=true, APP_URL=http://localhost:8000
|
||||||
# Поменять DB_HOST=127.0.0.1, DB_USERNAME=root, убрать DB_ROOT_PASSWORD
|
|
||||||
php artisan key:generate
|
php artisan key:generate
|
||||||
|
|
||||||
|
touch database/sqlite/database.sqlite
|
||||||
php artisan migrate --seed
|
php artisan migrate --seed
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -34,13 +35,22 @@ php artisan serve
|
|||||||
npm run dev
|
npm run dev
|
||||||
```
|
```
|
||||||
|
|
||||||
Приложение: [http://127.0.0.1:8000](http://127.0.0.1:8000)
|
Приложение: http://127.0.0.1:8000
|
||||||
|
|
||||||
|
**Тестовые аккаунты** (пароль у всех: `password`):
|
||||||
|
|
||||||
|
| Email | Роль |
|
||||||
|
|---|---|
|
||||||
|
| admin@service.local | Администратор |
|
||||||
|
| manager@service.local | Менеджер |
|
||||||
|
| tech1@service.local | Техник |
|
||||||
|
| client1@service.local | Клиент |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Деплой на сервер (flamy / docker-runtime)
|
## Деплой на сервер (Docker)
|
||||||
|
|
||||||
**Требования:** Docker, Docker Compose на `docker-runtime` (`10.20.0.20`).
|
**Требования:** Docker, Docker Compose на сервере `10.20.0.20`.
|
||||||
|
|
||||||
### 1. Скопировать проект на сервер
|
### 1. Скопировать проект на сервер
|
||||||
|
|
||||||
@@ -49,7 +59,7 @@ ssh -i /root/.ssh/docker_vm_ed25519 crimson@10.20.0.20
|
|||||||
sudo mkdir -p /opt/docker-apps/airservice
|
sudo mkdir -p /opt/docker-apps/airservice
|
||||||
```
|
```
|
||||||
|
|
||||||
Скопировать файлы (с локальной машины):
|
С локальной машины:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
rsync -avz --exclude='.git' --exclude='node_modules' --exclude='vendor' \
|
rsync -avz --exclude='.git' --exclude='node_modules' --exclude='vendor' \
|
||||||
@@ -67,27 +77,62 @@ nano .env
|
|||||||
Обязательно заполнить:
|
Обязательно заполнить:
|
||||||
|
|
||||||
```env
|
```env
|
||||||
APP_KEY= # php artisan key:generate --show
|
APP_KEY= # сгенерировать ниже
|
||||||
APP_URL=https://your-domain.ru
|
APP_URL=https://your-domain.ru
|
||||||
DB_PASSWORD= # придумать
|
|
||||||
DB_ROOT_PASSWORD= # придумать
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### 3. Запустить
|
Сгенерировать ключ:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose run --rm app php artisan key:generate --show
|
||||||
|
# Скопировать результат в APP_KEY= в .env
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Собрать и запустить
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker compose up -d --build
|
docker compose up -d --build
|
||||||
docker compose ps
|
|
||||||
docker compose logs -f --tail=100
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Проверить локально на сервере:
|
### 4. Наполнить базу начальными данными (один раз)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
docker compose exec app php artisan db:seed
|
||||||
|
```
|
||||||
|
|
||||||
|
После этого доступны тестовые аккаунты из таблицы выше.
|
||||||
|
|
||||||
|
### 5. Проверить
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose ps
|
||||||
|
docker compose logs app --tail=50
|
||||||
curl -I http://10.20.0.20:18201
|
curl -I http://10.20.0.20:18201
|
||||||
```
|
```
|
||||||
|
|
||||||
### 4. Открыть домен через Caddy (edge-proxy)
|
### Пересборка после обновления кода
|
||||||
|
|
||||||
|
```bash
|
||||||
|
rsync -avz --exclude='.git' --exclude='node_modules' --exclude='vendor' \
|
||||||
|
./ crimson@10.20.0.20:/opt/docker-apps/airservice/
|
||||||
|
|
||||||
|
docker compose up -d --build
|
||||||
|
```
|
||||||
|
|
||||||
|
Миграции накатываются автоматически при старте контейнера. База данных (SQLite файл) хранится в Docker volume `airservice_sqlite_data` и не теряется при пересборке.
|
||||||
|
|
||||||
|
### Если нужно сбросить базу и накатить заново
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose down
|
||||||
|
docker volume rm airservice_sqlite_data
|
||||||
|
docker compose up -d --build
|
||||||
|
docker compose exec app php artisan db:seed
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Открыть домен через Caddy (edge-proxy)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
ssh -i /root/.ssh/edge_vm_ed25519 crimson@192.168.0.80
|
ssh -i /root/.ssh/edge_vm_ed25519 crimson@192.168.0.80
|
||||||
@@ -121,8 +166,7 @@ sudo systemctl reload caddy
|
|||||||
## Структура Docker-сервисов
|
## Структура Docker-сервисов
|
||||||
|
|
||||||
| Сервис | Описание |
|
| Сервис | Описание |
|
||||||
|--------------------|-----------------------------------|
|
|---|---|
|
||||||
| `airservice_app` | PHP-FPM (Laravel) |
|
| `airservice_app` | PHP-FPM (Laravel) |
|
||||||
| `airservice_nginx` | nginx, публикует порт `18201` |
|
| `airservice_nginx` | nginx, порт `18201` |
|
||||||
| `airservice_mysql` | MySQL 8.0, только внутри сети |
|
| `airservice_queue` | Queue worker |
|
||||||
| `airservice_queue` | Queue worker (`queue:work`) |
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
namespace App\Providers;
|
namespace App\Providers;
|
||||||
|
|
||||||
use App\Models\Setting;
|
use App\Models\Setting;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
use Illuminate\Support\ServiceProvider;
|
use Illuminate\Support\ServiceProvider;
|
||||||
|
|
||||||
class AppServiceProvider extends ServiceProvider
|
class AppServiceProvider extends ServiceProvider
|
||||||
@@ -20,6 +21,13 @@ class AppServiceProvider extends ServiceProvider
|
|||||||
*/
|
*/
|
||||||
public function boot(): void
|
public function boot(): void
|
||||||
{
|
{
|
||||||
|
if (config('database.default') === 'sqlite') {
|
||||||
|
DB::statement('PRAGMA journal_mode=WAL');
|
||||||
|
DB::statement('PRAGMA synchronous=NORMAL');
|
||||||
|
DB::statement('PRAGMA busy_timeout=5000');
|
||||||
|
DB::statement('PRAGMA foreign_keys=ON');
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$companyName = Setting::query()->where('key', 'company_name')->value('value');
|
$companyName = Setting::query()->where('key', 'company_name')->value('value');
|
||||||
$timezone = Setting::query()->where('key', 'timezone')->value('value');
|
$timezone = Setting::query()->where('key', 'timezone')->value('value');
|
||||||
|
|||||||
@@ -25,10 +25,13 @@ class RequestService
|
|||||||
{
|
{
|
||||||
return DB::transaction(function () use ($data, $actor): ServiceRequest {
|
return DB::transaction(function () use ($data, $actor): ServiceRequest {
|
||||||
$payload = $this->preparePayload($data);
|
$payload = $this->preparePayload($data);
|
||||||
$payload['ticket_number'] = $this->generateTicketNumber();
|
$payload['ticket_number'] = 'PENDING-' . uniqid('', true);
|
||||||
|
|
||||||
$request = ServiceRequest::query()->create($payload);
|
$request = ServiceRequest::query()->create($payload);
|
||||||
|
|
||||||
|
$request->ticket_number = sprintf('SRV-%04d', $request->id);
|
||||||
|
$request->saveQuietly();
|
||||||
|
|
||||||
$this->persistAttachments($request, Arr::get($data, 'attachments', []), $actor);
|
$this->persistAttachments($request, Arr::get($data, 'attachments', []), $actor);
|
||||||
|
|
||||||
event(new RequestCreated($request, $actor));
|
event(new RequestCreated($request, $actor));
|
||||||
@@ -111,11 +114,9 @@ class RequestService
|
|||||||
return $map[$request->status?->slug ?? StatusSlug::NEW->value] ?? [];
|
return $map[$request->status?->slug ?? StatusSlug::NEW->value] ?? [];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function generateTicketNumber(): string
|
public function generateTicketNumber(int $id): string
|
||||||
{
|
{
|
||||||
$maxId = ServiceRequest::withTrashed()->max('id') ?? 0;
|
return sprintf('SRV-%04d', $id);
|
||||||
|
|
||||||
return sprintf('SRV-%04d', $maxId + 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function preparePayload(array $data, ?ServiceRequest $request = null): array
|
private function preparePayload(array $data, ?ServiceRequest $request = null): array
|
||||||
|
|||||||
+1
-1
@@ -15,7 +15,7 @@ return [
|
|||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'default' => env('DB_CONNECTION', 'mysql'),
|
'default' => env('DB_CONNECTION', 'sqlite'),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
|
|||||||
+2
-2
@@ -85,7 +85,7 @@ return [
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
'batching' => [
|
'batching' => [
|
||||||
'database' => env('DB_CONNECTION', 'mysql'),
|
'database' => env('DB_CONNECTION', 'sqlite'),
|
||||||
'table' => 'job_batches',
|
'table' => 'job_batches',
|
||||||
],
|
],
|
||||||
|
|
||||||
@@ -102,7 +102,7 @@ return [
|
|||||||
|
|
||||||
'failed' => [
|
'failed' => [
|
||||||
'driver' => env('QUEUE_FAILED_DRIVER', 'database-uuids'),
|
'driver' => env('QUEUE_FAILED_DRIVER', 'database-uuids'),
|
||||||
'database' => env('DB_CONNECTION', 'mysql'),
|
'database' => env('DB_CONNECTION', 'sqlite'),
|
||||||
'table' => 'failed_jobs',
|
'table' => 'failed_jobs',
|
||||||
],
|
],
|
||||||
|
|
||||||
|
|||||||
@@ -18,28 +18,75 @@ class ServiceRequestSeeder extends Seeder
|
|||||||
{
|
{
|
||||||
$types = RequestType::query()->get();
|
$types = RequestType::query()->get();
|
||||||
$priorities = Priority::query()->orderBy('level')->get();
|
$priorities = Priority::query()->orderBy('level')->get();
|
||||||
$statuses = Status::query()->get();
|
$statuses = Status::query()->get()->keyBy('slug');
|
||||||
$clients = User::query()->where('role', 'client')->get();
|
$clients = User::query()->where('role', 'client')->get();
|
||||||
$techs = User::query()->where('role', 'technician')->get();
|
$techs = User::query()->where('role', 'technician')->get();
|
||||||
$equipment = Equipment::query()->get();
|
$equipment = Equipment::query()->get();
|
||||||
|
|
||||||
for ($i = 1; $i <= 25; $i++) {
|
// Распределение: 10 активных, 8 в ожидании/в работе с дедлайном сегодня-завтра,
|
||||||
|
// 4 решённых, 3 закрытых.
|
||||||
|
$buckets = [
|
||||||
|
// [slug, count, deadline_offset_hours от now]
|
||||||
|
['new', 4, [+48, +168]], // новые — дедлайн через 2-7 дней
|
||||||
|
['in_progress', 6, [+4, +48]], // в работе — дедлайн через 4-48 ч
|
||||||
|
['waiting', 4, [+24, +96]], // ожидание — дедлайн через 1-4 дня
|
||||||
|
['resolved', 5, [-72, -1]], // решены — дедлайн в прошлом
|
||||||
|
['closed', 4, [-168, -24]], // закрыты — дедлайн в прошлом
|
||||||
|
['cancelled', 2, [-240, -48]], // отменены
|
||||||
|
];
|
||||||
|
|
||||||
|
$counter = 1;
|
||||||
|
|
||||||
|
foreach ($buckets as [$slug, $count, [$dlMin, $dlMax]]) {
|
||||||
|
$status = $statuses[$slug] ?? $statuses->first();
|
||||||
|
|
||||||
|
for ($i = 0; $i < $count; $i++) {
|
||||||
$type = $types->random();
|
$type = $types->random();
|
||||||
$priority = $priorities->random();
|
$priority = $priorities->random();
|
||||||
$status = $statuses->random();
|
|
||||||
$client = $clients->random();
|
$client = $clients->random();
|
||||||
$assignee = $techs->random();
|
$assignee = $techs->random();
|
||||||
$createdAt = now()->subDays(rand(0, 20))->subHours(rand(0, 23));
|
|
||||||
$deadlineAt = (clone $createdAt)->addHours($type->sla_hours);
|
$deadlineAt = now()->addHours(rand($dlMin, $dlMax));
|
||||||
|
|
||||||
|
// created_at: задолго до дедлайна, но реалистично
|
||||||
|
$createdAt = (clone $deadlineAt)->subHours($type->sla_hours + rand(0, 12));
|
||||||
|
|
||||||
|
// Не даём created_at быть в будущем
|
||||||
|
if ($createdAt->isFuture()) {
|
||||||
|
$createdAt = now()->subMinutes(rand(10, 120));
|
||||||
|
}
|
||||||
|
|
||||||
|
$startedAt = null;
|
||||||
|
$completedAt = null;
|
||||||
|
$resolutionNotes = null;
|
||||||
|
$clientRating = null;
|
||||||
|
$clientComment = null;
|
||||||
|
|
||||||
|
if (in_array($slug, ['in_progress', 'resolved', 'closed'])) {
|
||||||
|
$startedAt = (clone $createdAt)->addHours(rand(1, 4));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (in_array($slug, ['resolved', 'closed'])) {
|
||||||
|
$completedAt = (clone $deadlineAt)->subHours(rand(0, 6));
|
||||||
|
$resolutionNotes = fake()->sentence(12);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($slug === 'closed') {
|
||||||
|
$clientRating = rand(3, 5);
|
||||||
|
$clientComment = fake()->sentence();
|
||||||
|
}
|
||||||
|
|
||||||
$request = ServiceRequest::query()->create([
|
$request = ServiceRequest::query()->create([
|
||||||
'ticket_number' => sprintf('SRV-%04d', $i),
|
'ticket_number' => sprintf('SRV-%04d', $counter),
|
||||||
'title' => fake()->randomElement([
|
'title' => fake()->randomElement([
|
||||||
'Не включается рабочая станция',
|
'Не включается рабочая станция',
|
||||||
'Проблема с печатью документов',
|
'Проблема с печатью документов',
|
||||||
'Нет доступа к корпоративной сети',
|
'Нет доступа к корпоративной сети',
|
||||||
'Требуется установка ПО',
|
'Требуется установка ПО',
|
||||||
'Сильный шум вентилятора',
|
'Сильный шум вентилятора',
|
||||||
|
'Зависает операционная система',
|
||||||
|
'Не работает монитор',
|
||||||
|
'Проблема с принтером',
|
||||||
]),
|
]),
|
||||||
'description' => fake()->paragraph(3),
|
'description' => fake()->paragraph(3),
|
||||||
'type_id' => $type->id,
|
'type_id' => $type->id,
|
||||||
@@ -49,28 +96,26 @@ class ServiceRequestSeeder extends Seeder
|
|||||||
'assigned_to' => $assignee->id,
|
'assigned_to' => $assignee->id,
|
||||||
'equipment_id' => rand(0, 100) > 20 ? $equipment->random()?->id : null,
|
'equipment_id' => rand(0, 100) > 20 ? $equipment->random()?->id : null,
|
||||||
'location' => fake()->randomElement(['Офис 101', 'Офис 204', 'Склад', 'Переговорная 2']),
|
'location' => fake()->randomElement(['Офис 101', 'Офис 204', 'Склад', 'Переговорная 2']),
|
||||||
'planned_at' => rand(0, 100) > 50 ? $createdAt->copy()->addHours(rand(2, 24)) : null,
|
'planned_at' => rand(0, 100) > 50 ? (clone $createdAt)->addHours(rand(2, 24)) : null,
|
||||||
'deadline_at' => $deadlineAt,
|
'deadline_at' => $deadlineAt,
|
||||||
'started_at' => rand(0, 100) > 40 ? $createdAt->copy()->addHours(rand(1, 8)) : null,
|
'started_at' => $startedAt,
|
||||||
'completed_at' => $status->is_final ? $deadlineAt->copy()->subHours(rand(0, 6)) : null,
|
'completed_at' => $completedAt,
|
||||||
'resolution_notes' => $status->slug === 'resolved' || $status->slug === 'closed'
|
'resolution_notes' => $resolutionNotes,
|
||||||
? fake()->sentence(12)
|
'client_rating' => $clientRating,
|
||||||
: null,
|
'client_comment' => $clientComment,
|
||||||
'client_rating' => $status->slug === 'closed' ? rand(3, 5) : null,
|
|
||||||
'client_comment' => $status->slug === 'closed' ? fake()->sentence() : null,
|
|
||||||
'created_at' => $createdAt,
|
'created_at' => $createdAt,
|
||||||
'updated_at' => now(),
|
'updated_at' => now(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
for ($commentIndex = 1; $commentIndex <= rand(1, 3); $commentIndex++) {
|
for ($c = 1; $c <= rand(1, 3); $c++) {
|
||||||
$author = rand(0, 1) ? $client : $assignee;
|
$author = rand(0, 1) ? $client : $assignee;
|
||||||
RequestComment::query()->create([
|
RequestComment::query()->create([
|
||||||
'request_id' => $request->id,
|
'request_id' => $request->id,
|
||||||
'user_id' => $author->id,
|
'user_id' => $author->id,
|
||||||
'body' => fake()->sentence(rand(10, 20)),
|
'body' => fake()->sentence(rand(10, 20)),
|
||||||
'is_internal' => $author->role !== 'client' && rand(0, 100) > 60,
|
'is_internal' => $author->role !== 'client' && rand(0, 100) > 60,
|
||||||
'created_at' => $createdAt->copy()->addHours($commentIndex),
|
'created_at' => (clone $createdAt)->addHours($c),
|
||||||
'updated_at' => $createdAt->copy()->addHours($commentIndex),
|
'updated_at' => (clone $createdAt)->addHours($c),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,6 +128,9 @@ class ServiceRequestSeeder extends Seeder
|
|||||||
'ip_address' => '127.0.0.1',
|
'ip_address' => '127.0.0.1',
|
||||||
'created_at' => $createdAt,
|
'created_at' => $createdAt,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
$counter++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-26
@@ -15,11 +15,9 @@ services:
|
|||||||
volumes:
|
volumes:
|
||||||
- storage_uploads:/var/www/html/storage/app/public
|
- storage_uploads:/var/www/html/storage/app/public
|
||||||
- storage_logs:/var/www/html/storage/logs
|
- storage_logs:/var/www/html/storage/logs
|
||||||
|
- sqlite_data:/var/www/html/database/sqlite
|
||||||
networks:
|
networks:
|
||||||
- backend
|
- backend
|
||||||
depends_on:
|
|
||||||
mysql:
|
|
||||||
condition: service_healthy
|
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: ["CMD-SHELL", "php-fpm -t 2>&1 | grep -q 'successful' && echo ok || exit 1"]
|
test: ["CMD-SHELL", "php-fpm -t 2>&1 | grep -q 'successful' && echo ok || exit 1"]
|
||||||
interval: 30s
|
interval: 30s
|
||||||
@@ -40,34 +38,13 @@ services:
|
|||||||
volumes:
|
volumes:
|
||||||
- storage_uploads:/var/www/html/storage/app/public
|
- storage_uploads:/var/www/html/storage/app/public
|
||||||
- storage_logs:/var/www/html/storage/logs
|
- storage_logs:/var/www/html/storage/logs
|
||||||
|
- sqlite_data:/var/www/html/database/sqlite
|
||||||
networks:
|
networks:
|
||||||
- backend
|
- backend
|
||||||
depends_on:
|
depends_on:
|
||||||
app:
|
app:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
|
|
||||||
mysql:
|
|
||||||
image: mysql:8.0
|
|
||||||
container_name: airservice_mysql
|
|
||||||
restart: unless-stopped
|
|
||||||
environment:
|
|
||||||
MYSQL_DATABASE: ${DB_DATABASE}
|
|
||||||
MYSQL_USER: ${DB_USERNAME}
|
|
||||||
MYSQL_PASSWORD: ${DB_PASSWORD}
|
|
||||||
MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
|
|
||||||
expose:
|
|
||||||
- "3306"
|
|
||||||
volumes:
|
|
||||||
- mysql_data:/var/lib/mysql
|
|
||||||
networks:
|
|
||||||
- backend
|
|
||||||
healthcheck:
|
|
||||||
test: ["CMD", "mysqladmin", "ping", "-h", "127.0.0.1", "-u", "root", "--password=${DB_ROOT_PASSWORD}"]
|
|
||||||
interval: 10s
|
|
||||||
timeout: 5s
|
|
||||||
retries: 10
|
|
||||||
start_period: 30s
|
|
||||||
|
|
||||||
nginx:
|
nginx:
|
||||||
build:
|
build:
|
||||||
context: .
|
context: .
|
||||||
@@ -96,6 +73,6 @@ networks:
|
|||||||
driver: bridge
|
driver: bridge
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
mysql_data:
|
sqlite_data:
|
||||||
storage_uploads:
|
storage_uploads:
|
||||||
storage_logs:
|
storage_logs:
|
||||||
|
|||||||
@@ -1,6 +1,16 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
|
if [ "$DB_CONNECTION" = "sqlite" ]; then
|
||||||
|
DB_DIR=$(dirname "$DB_DATABASE")
|
||||||
|
mkdir -p "$DB_DIR"
|
||||||
|
if [ ! -f "$DB_DATABASE" ]; then
|
||||||
|
touch "$DB_DATABASE"
|
||||||
|
fi
|
||||||
|
chown -R www-data:www-data "$DB_DIR"
|
||||||
|
chmod 664 "$DB_DATABASE"
|
||||||
|
fi
|
||||||
|
|
||||||
php artisan migrate --force
|
php artisan migrate --force
|
||||||
php artisan config:cache
|
php artisan config:cache
|
||||||
php artisan route:cache
|
php artisan route:cache
|
||||||
|
|||||||
Reference in New Issue
Block a user