commit
2468251f56
25
app/Console/Commands/CleanupApplicationDeploymentQueue.php
Normal file
25
app/Console/Commands/CleanupApplicationDeploymentQueue.php
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Console\Commands;
|
||||||
|
|
||||||
|
use App\Models\ApplicationDeploymentQueue;
|
||||||
|
use Illuminate\Console\Command;
|
||||||
|
|
||||||
|
class CleanupApplicationDeploymentQueue extends Command
|
||||||
|
{
|
||||||
|
protected $signature = 'cleanup:application-deployment-queue {--team-id=}';
|
||||||
|
protected $description = 'CleanupApplicationDeploymentQueue';
|
||||||
|
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
$team_id = $this->option('team-id');
|
||||||
|
$servers = \App\Models\Server::where('team_id', $team_id)->get();
|
||||||
|
foreach ($servers as $server) {
|
||||||
|
$deployments = ApplicationDeploymentQueue::whereIn("status", ["in_progress", "queued"])->where("server_id", $server->id)->get();
|
||||||
|
foreach ($deployments as $deployment) {
|
||||||
|
$deployment->update(['status' => 'failed']);
|
||||||
|
instant_remote_process(['docker rm -f ' . $deployment->deployment_uuid], $server, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -167,65 +167,71 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
|
|||||||
if ($this->application->is_github_based()) {
|
if ($this->application->is_github_based()) {
|
||||||
ApplicationPullRequestUpdateJob::dispatch(application: $this->application, preview: $this->preview, deployment_uuid: $this->deployment_uuid, status: ProcessStatus::IN_PROGRESS);
|
ApplicationPullRequestUpdateJob::dispatch(application: $this->application, preview: $this->preview, deployment_uuid: $this->deployment_uuid, status: ProcessStatus::IN_PROGRESS);
|
||||||
}
|
}
|
||||||
|
if ($this->application->build_pack === 'dockerfile') {
|
||||||
|
if (data_get($this->application, 'dockerfile_location')) {
|
||||||
|
$this->dockerfile_location = $this->application->dockerfile_location;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function handle(): void
|
public function handle(): void
|
||||||
{
|
{
|
||||||
// Generate custom host<->ip mapping
|
try {
|
||||||
$allContainers = instant_remote_process(["docker network inspect {$this->destination->network} -f '{{json .Containers}}' "], $this->server);
|
// Generate custom host<->ip mapping
|
||||||
if (!is_null($allContainers)) {
|
$allContainers = instant_remote_process(["docker network inspect {$this->destination->network} -f '{{json .Containers}}' "], $this->server);
|
||||||
$allContainers = format_docker_command_output_to_json($allContainers);
|
|
||||||
$ips = collect([]);
|
if (!is_null($allContainers)) {
|
||||||
if (count($allContainers) > 0) {
|
$allContainers = format_docker_command_output_to_json($allContainers);
|
||||||
$allContainers = $allContainers[0];
|
$ips = collect([]);
|
||||||
$allContainers = collect($allContainers)->sort()->values();
|
if (count($allContainers) > 0) {
|
||||||
foreach ($allContainers as $container) {
|
$allContainers = $allContainers[0];
|
||||||
$containerName = data_get($container, 'Name');
|
$allContainers = collect($allContainers)->sort()->values();
|
||||||
if ($containerName === 'coolify-proxy') {
|
foreach ($allContainers as $container) {
|
||||||
continue;
|
$containerName = data_get($container, 'Name');
|
||||||
}
|
if ($containerName === 'coolify-proxy') {
|
||||||
if (preg_match('/-(\d{12})/', $containerName)) {
|
continue;
|
||||||
continue;
|
}
|
||||||
}
|
if (preg_match('/-(\d{12})/', $containerName)) {
|
||||||
$containerIp = data_get($container, 'IPv4Address');
|
continue;
|
||||||
if ($containerName && $containerIp) {
|
}
|
||||||
$containerIp = str($containerIp)->before('/');
|
$containerIp = data_get($container, 'IPv4Address');
|
||||||
$ips->put($containerName, $containerIp->value());
|
if ($containerName && $containerIp) {
|
||||||
|
$containerIp = str($containerIp)->before('/');
|
||||||
|
$ips->put($containerName, $containerIp->value());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
$this->addHosts = $ips->map(function ($ip, $name) {
|
||||||
|
return "--add-host $name:$ip";
|
||||||
|
})->implode(' ');
|
||||||
}
|
}
|
||||||
$this->addHosts = $ips->map(function ($ip, $name) {
|
|
||||||
return "--add-host $name:$ip";
|
|
||||||
})->implode(' ');
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($this->application->dockerfile_target_build) {
|
if ($this->application->dockerfile_target_build) {
|
||||||
$this->buildTarget = " --target {$this->application->dockerfile_target_build} ";
|
$this->buildTarget = " --target {$this->application->dockerfile_target_build} ";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check custom port
|
// Check custom port
|
||||||
['repository' => $this->customRepository, 'port' => $this->customPort] = $this->application->customRepository();
|
['repository' => $this->customRepository, 'port' => $this->customPort] = $this->application->customRepository();
|
||||||
|
|
||||||
if (data_get($this->application, 'settings.is_build_server_enabled')) {
|
if (data_get($this->application, 'settings.is_build_server_enabled')) {
|
||||||
$teamId = data_get($this->application, 'environment.project.team.id');
|
$teamId = data_get($this->application, 'environment.project.team.id');
|
||||||
$buildServers = Server::buildServers($teamId)->get();
|
$buildServers = Server::buildServers($teamId)->get();
|
||||||
if ($buildServers->count() === 0) {
|
if ($buildServers->count() === 0) {
|
||||||
$this->application_deployment_queue->addLogEntry("Build server feature activated, but no suitable build server found. Using the deployment server.");
|
$this->application_deployment_queue->addLogEntry("Build server feature activated, but no suitable build server found. Using the deployment server.");
|
||||||
|
$this->build_server = $this->server;
|
||||||
|
$this->original_server = $this->server;
|
||||||
|
} else {
|
||||||
|
$this->application_deployment_queue->addLogEntry("Build server feature activated and found a suitable build server. Using it to build your application - if needed.");
|
||||||
|
$this->build_server = $buildServers->random();
|
||||||
|
$this->original_server = $this->server;
|
||||||
|
$this->use_build_server = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Set build server & original_server to the same as deployment server
|
||||||
$this->build_server = $this->server;
|
$this->build_server = $this->server;
|
||||||
$this->original_server = $this->server;
|
$this->original_server = $this->server;
|
||||||
} else {
|
|
||||||
$this->application_deployment_queue->addLogEntry("Build server feature activated and found a suitable build server. Using it to build your application - if needed.");
|
|
||||||
$this->build_server = $buildServers->random();
|
|
||||||
$this->original_server = $this->server;
|
|
||||||
$this->use_build_server = true;
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
// Set build server & original_server to the same as deployment server
|
|
||||||
$this->build_server = $this->server;
|
|
||||||
$this->original_server = $this->server;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
if ($this->restart_only && $this->application->build_pack !== 'dockerimage') {
|
if ($this->restart_only && $this->application->build_pack !== 'dockerimage') {
|
||||||
$this->just_restart();
|
$this->just_restart();
|
||||||
if ($this->server->isProxyShouldRun()) {
|
if ($this->server->isProxyShouldRun()) {
|
||||||
@ -1660,6 +1666,8 @@ COPY ./nginx.conf /etc/nginx/conf.d/default.conf");
|
|||||||
|
|
||||||
public function failed(Throwable $exception): void
|
public function failed(Throwable $exception): void
|
||||||
{
|
{
|
||||||
|
|
||||||
|
$this->next(ApplicationDeploymentStatus::FAILED->value);
|
||||||
$this->application_deployment_queue->addLogEntry("Oops something is not okay, are you okay? 😢", 'stderr');
|
$this->application_deployment_queue->addLogEntry("Oops something is not okay, are you okay? 😢", 'stderr');
|
||||||
if (str($exception->getMessage())->isNotEmpty()) {
|
if (str($exception->getMessage())->isNotEmpty()) {
|
||||||
$this->application_deployment_queue->addLogEntry($exception->getMessage(), 'stderr');
|
$this->application_deployment_queue->addLogEntry($exception->getMessage(), 'stderr');
|
||||||
@ -1667,6 +1675,7 @@ COPY ./nginx.conf /etc/nginx/conf.d/default.conf");
|
|||||||
|
|
||||||
if ($this->application->build_pack !== 'dockercompose') {
|
if ($this->application->build_pack !== 'dockercompose') {
|
||||||
$code = $exception->getCode();
|
$code = $exception->getCode();
|
||||||
|
ray($code);
|
||||||
if ($code !== 69420) {
|
if ($code !== 69420) {
|
||||||
// 69420 means failed to push the image to the registry, so we don't need to remove the new version as it is the currently running one
|
// 69420 means failed to push the image to the registry, so we don't need to remove the new version as it is the currently running one
|
||||||
$this->application_deployment_queue->addLogEntry("Deployment failed. Removing the new version of your application.", 'stderr');
|
$this->application_deployment_queue->addLogEntry("Deployment failed. Removing the new version of your application.", 'stderr');
|
||||||
@ -1675,6 +1684,5 @@ COPY ./nginx.conf /etc/nginx/conf.d/default.conf");
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$this->next(ApplicationDeploymentStatus::FAILED->value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,30 +15,26 @@ class Index extends Component
|
|||||||
if (!isCloud()) {
|
if (!isCloud()) {
|
||||||
return redirect()->route('dashboard');
|
return redirect()->route('dashboard');
|
||||||
}
|
}
|
||||||
if (auth()->user()->id !== 0 && session('adminToken') === null) {
|
if (auth()->user()->id !== 0) {
|
||||||
return redirect()->route('dashboard');
|
return redirect()->route('dashboard');
|
||||||
}
|
}
|
||||||
$this->users = User::whereHas('teams', function ($query) {
|
$this->users = User::whereHas('teams', function ($query) {
|
||||||
$query->whereRelation('subscription', 'stripe_subscription_id', '!=', null);
|
$query->whereRelation('subscription', 'stripe_subscription_id', '!=', null);
|
||||||
})->get();
|
})->get()->filter(function ($user) {
|
||||||
|
return $user->id !== 0;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
public function switchUser(int $user_id)
|
public function switchUser(int $user_id)
|
||||||
{
|
{
|
||||||
$user = User::find($user_id);
|
if (auth()->user()->id !== 0) {
|
||||||
auth()->login($user);
|
return redirect()->route('dashboard');
|
||||||
|
|
||||||
if ($user_id === 0) {
|
|
||||||
Cache::forget('team:0');
|
|
||||||
session()->forget('adminToken');
|
|
||||||
} else {
|
|
||||||
$token_payload = [
|
|
||||||
'valid' => true,
|
|
||||||
];
|
|
||||||
$token = Crypt::encrypt($token_payload);
|
|
||||||
session(['adminToken' => $token]);
|
|
||||||
}
|
}
|
||||||
session()->regenerate();
|
$user = User::find($user_id);
|
||||||
return refreshSession();
|
$team_to_switch_to = $user->teams->first();
|
||||||
|
Cache::forget("team:{$user->id}");
|
||||||
|
auth()->login($user);
|
||||||
|
refreshSession($team_to_switch_to);
|
||||||
|
return redirect(request()->header('Referer'));
|
||||||
}
|
}
|
||||||
public function render()
|
public function render()
|
||||||
{
|
{
|
||||||
|
@ -23,8 +23,8 @@ class Dashboard extends Component
|
|||||||
public function cleanup_queue()
|
public function cleanup_queue()
|
||||||
{
|
{
|
||||||
$this->dispatch('success', 'Cleanup started.');
|
$this->dispatch('success', 'Cleanup started.');
|
||||||
Artisan::queue('app:init', [
|
Artisan::queue('cleanup:application-deployment-queue', [
|
||||||
'--cleanup-deployments' => 'true'
|
'--team-id' => currentTeam()->id
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
public function get_deployments()
|
public function get_deployments()
|
||||||
|
@ -29,8 +29,8 @@ class Import extends Component
|
|||||||
public string $container;
|
public string $container;
|
||||||
public array $importCommands = [];
|
public array $importCommands = [];
|
||||||
public string $postgresqlRestoreCommand = 'pg_restore -U $POSTGRES_USER -d $POSTGRES_DB';
|
public string $postgresqlRestoreCommand = 'pg_restore -U $POSTGRES_USER -d $POSTGRES_DB';
|
||||||
public string $mysqlRestoreCommand = 'mysql -u $MYSQL_USER -p $MYSQL_PASSWORD $MYSQL_DATABASE';
|
public string $mysqlRestoreCommand = 'mysql -u $MYSQL_USER -p$MYSQL_PASSWORD $MYSQL_DATABASE';
|
||||||
public string $mariadbRestoreCommand = 'mariadb -u $MARIADB_USER -p $MARIADB_PASSWORD $MARIADB_DATABASE';
|
public string $mariadbRestoreCommand = 'mariadb -u $MARIADB_USER -p$MARIADB_PASSWORD $MARIADB_DATABASE';
|
||||||
|
|
||||||
public function getListeners()
|
public function getListeners()
|
||||||
{
|
{
|
||||||
|
@ -64,7 +64,7 @@ class Navbar extends Component
|
|||||||
StopService::run($this->service);
|
StopService::run($this->service);
|
||||||
$this->service->refresh();
|
$this->service->refresh();
|
||||||
if ($forceCleanup) {
|
if ($forceCleanup) {
|
||||||
$this->dispatch('success', 'Force cleanup service.');
|
$this->dispatch('success', 'Containers cleaned up.');
|
||||||
} else {
|
} else {
|
||||||
$this->dispatch('success', 'Service stopped.');
|
$this->dispatch('success', 'Service stopped.');
|
||||||
}
|
}
|
||||||
|
@ -107,6 +107,9 @@ class ExecuteContainerCommand extends Component
|
|||||||
{
|
{
|
||||||
$this->validate();
|
$this->validate();
|
||||||
try {
|
try {
|
||||||
|
if ($this->server->isForceDisabled()) {
|
||||||
|
throw new \RuntimeException('Server is disabled.');
|
||||||
|
}
|
||||||
// Wrap command to prevent escaped execution in the host.
|
// Wrap command to prevent escaped execution in the host.
|
||||||
$cmd = 'sh -c "if [ -f ~/.profile ]; then . ~/.profile; fi; ' . str_replace('"', '\"', $this->command) . '"';
|
$cmd = 'sh -c "if [ -f ~/.profile ]; then . ~/.profile; fi; ' . str_replace('"', '\"', $this->command) . '"';
|
||||||
if (!empty($this->workDir)) {
|
if (!empty($this->workDir)) {
|
||||||
|
@ -147,11 +147,11 @@ class Server extends BaseModel
|
|||||||
public function skipServer()
|
public function skipServer()
|
||||||
{
|
{
|
||||||
if ($this->ip === '1.2.3.4') {
|
if ($this->ip === '1.2.3.4') {
|
||||||
ray('skipping 1.2.3.4');
|
// ray('skipping 1.2.3.4');
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if ($this->settings->force_disabled === true) {
|
if ($this->settings->force_disabled === true) {
|
||||||
ray('force_disabled');
|
// ray('force_disabled');
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -24,12 +24,6 @@ trait ExecuteRemoteCommand
|
|||||||
if ($this->server instanceof Server === false) {
|
if ($this->server instanceof Server === false) {
|
||||||
throw new \RuntimeException('Server is not set or is not an instance of Server model');
|
throw new \RuntimeException('Server is not set or is not an instance of Server model');
|
||||||
}
|
}
|
||||||
if ($this->server->settings->force_disabled) {
|
|
||||||
$this->application_deployment_queue->update([
|
|
||||||
'status' => ApplicationDeploymentStatus::FAILED->value,
|
|
||||||
]);
|
|
||||||
throw new \RuntimeException('Server is disabled');
|
|
||||||
}
|
|
||||||
$commandsText->each(function ($single_command) {
|
$commandsText->each(function ($single_command) {
|
||||||
$command = data_get($single_command, 'command') ?? $single_command[0] ?? null;
|
$command = data_get($single_command, 'command') ?? $single_command[0] ?? null;
|
||||||
if ($command === null) {
|
if ($command === null) {
|
||||||
|
@ -110,6 +110,9 @@ function instant_scp(string $source, string $dest, Server $server, $throwError =
|
|||||||
}
|
}
|
||||||
function generateSshCommand(Server $server, string $command)
|
function generateSshCommand(Server $server, string $command)
|
||||||
{
|
{
|
||||||
|
if ($server->settings->force_disabled) {
|
||||||
|
throw new \RuntimeException('Server is disabled.');
|
||||||
|
}
|
||||||
$user = $server->user;
|
$user = $server->user;
|
||||||
$port = $server->port;
|
$port = $server->port;
|
||||||
$privateKeyLocation = savePrivateKeyToFs($server);
|
$privateKeyLocation = savePrivateKeyToFs($server);
|
||||||
|
@ -7,7 +7,7 @@ return [
|
|||||||
|
|
||||||
// The release version of your application
|
// The release version of your application
|
||||||
// Example with dynamic git hash: trim(exec('git --git-dir ' . base_path('.git') . ' log --pretty="%h" -n1 HEAD'))
|
// Example with dynamic git hash: trim(exec('git --git-dir ' . base_path('.git') . ' log --pretty="%h" -n1 HEAD'))
|
||||||
'release' => '4.0.0-beta.225',
|
'release' => '4.0.0-beta.226',
|
||||||
// When left empty or `null` the Laravel environment will be used
|
// When left empty or `null` the Laravel environment will be used
|
||||||
'environment' => config('app.env'),
|
'environment' => config('app.env'),
|
||||||
|
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
return '4.0.0-beta.225';
|
return '4.0.0-beta.226';
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
{{ auth()->user()->name }}
|
{{ auth()->user()->name }}
|
||||||
<h3 class="pt-4">Users</h3>
|
<h3 class="pt-4">Users</h3>
|
||||||
<div class="flex flex-wrap gap-2">
|
<div class="flex flex-wrap gap-2">
|
||||||
<div class="w-96 box" wire:click="switchUser('0')">
|
<div class="text-white cursor-pointer w-96 box-without-bg bg-coollabs-100" wire:click="switchUser('0')">
|
||||||
Root
|
Root
|
||||||
</div>
|
</div>
|
||||||
@foreach ($users as $user)
|
@foreach ($users as $user)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<div>
|
<div>
|
||||||
<x-server.navbar :server="$server" :parameters="$parameters" />
|
<x-server.navbar :server="$server" :parameters="$parameters" />
|
||||||
<x-server.sidebar :server="$server" :parameters="$parameters" />
|
|
||||||
<div class="flex gap-2">
|
<div class="flex gap-2">
|
||||||
|
<x-server.sidebar :server="$server" :parameters="$parameters" />
|
||||||
<div class="w-full">
|
<div class="w-full">
|
||||||
@if ($server->isFunctional())
|
@if ($server->isFunctional())
|
||||||
<div class="flex gap-2">
|
<div class="flex gap-2">
|
||||||
|
100
templates/compose/invoice-ninja.yaml
Normal file
100
templates/compose/invoice-ninja.yaml
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
# ignore: true
|
||||||
|
# documentation: https://invoiceninja.github.io/selfhost.html
|
||||||
|
# slogan: The leading open-source invoicing platform
|
||||||
|
# tags: invoicing, billing, accounting, finance, self-hosted
|
||||||
|
|
||||||
|
services:
|
||||||
|
invoice-ninja:
|
||||||
|
image: invoiceninja/invoiceninja:5
|
||||||
|
environment:
|
||||||
|
- SERVICE_FQDN_INVOICENINJA
|
||||||
|
- APP_ENV=production
|
||||||
|
- APP_URL=${SERVICE_FQDN_INVOICENINJA}
|
||||||
|
- APP_KEY=${SERVICE_BASE64_INVOICENINJA}
|
||||||
|
- APP_DEBUG=false
|
||||||
|
- REQUIRE_HTTPS=false
|
||||||
|
- PHANTOMJS_PDF_GENERATION=false
|
||||||
|
- PDF_GENERATOR=snappdf
|
||||||
|
- TRUSTED_PROXIES=*
|
||||||
|
- QUEUE_CONNECTION=database
|
||||||
|
- DB_HOST=mysql
|
||||||
|
- DB_PORT=3306
|
||||||
|
- DB_DATABASE=${MYSQL_DATABASE:-invoice_ninja}
|
||||||
|
- DB_USERNAME=${SERVICE_USER_MYSQL}
|
||||||
|
- DB_PASSWORD=${SERVICE_PASSWORD_MYSQL}
|
||||||
|
volumes:
|
||||||
|
- invoice-ninja-public:/var/www/app/public
|
||||||
|
- invoice-ninja-storage:/var/www/app/storage
|
||||||
|
- type: bind
|
||||||
|
source: ./php.ini
|
||||||
|
target: /usr/local/etc/php/php.ini
|
||||||
|
content: |
|
||||||
|
session.auto_start = Off
|
||||||
|
short_open_tag = Off
|
||||||
|
|
||||||
|
error_reporting = E_ALL & ~E_NOTICE & ~E_WARNING & ~E_STRICT & ~E_DEPRECATED
|
||||||
|
|
||||||
|
; opcache.enable=1
|
||||||
|
; opcache.preload=/srv/www/invoiceninja/current/preload.php
|
||||||
|
; opcache.preload_user=www-data
|
||||||
|
|
||||||
|
; ; The OPcache shared memory storage size.
|
||||||
|
; opcache.max_accelerated_files=300000
|
||||||
|
; opcache.validate_timestamps=1
|
||||||
|
; opcache.revalidate_freq=30
|
||||||
|
; opcache.jit_buffer_size=256M
|
||||||
|
; opcache.jit=1205
|
||||||
|
; opcache.memory_consumption=1024M
|
||||||
|
|
||||||
|
|
||||||
|
post_max_size = 60M
|
||||||
|
upload_max_filesize = 50M
|
||||||
|
memory_limit=512M
|
||||||
|
- type: bind
|
||||||
|
source: ./php-cli.ini
|
||||||
|
target: /usr/local/etc/php/php-cli.ini
|
||||||
|
content: |
|
||||||
|
session.auto_start = Off
|
||||||
|
short_open_tag = Off
|
||||||
|
|
||||||
|
error_reporting = E_ALL & ~E_NOTICE & ~E_WARNING & ~E_STRICT & ~E_DEPRECATED
|
||||||
|
|
||||||
|
; opcache.enable_cli=1
|
||||||
|
; opcache.fast_shutdown=1
|
||||||
|
; opcache.memory_consumption=256
|
||||||
|
; opcache.interned_strings_buffer=8
|
||||||
|
; opcache.max_accelerated_files=4000
|
||||||
|
; opcache.revalidate_freq=60
|
||||||
|
; # http://symfony.com/doc/current/performance.html
|
||||||
|
; realpath_cache_size = 4096K
|
||||||
|
; realpath_cache_ttl = 600
|
||||||
|
|
||||||
|
memory_limit = 2G
|
||||||
|
post_max_size = 60M
|
||||||
|
upload_max_filesize = 50M
|
||||||
|
depends_on:
|
||||||
|
mysql:
|
||||||
|
condition: service_healthy
|
||||||
|
mysql:
|
||||||
|
image: mariadb:lts
|
||||||
|
environment:
|
||||||
|
- MYSQL_USER=${SERVICE_USER_MYSQL}
|
||||||
|
- MYSQL_PASSWORD=${SERVICE_PASSWORD_MYSQL}
|
||||||
|
- MYSQL_DATABASE=${MYSQL_DATABASE:-invoice_ninja}
|
||||||
|
- MYSQL_ROOT_PASSWORD=${SERVICE_PASSWORD_MYSQLROOT}
|
||||||
|
healthcheck:
|
||||||
|
test:
|
||||||
|
[
|
||||||
|
"CMD",
|
||||||
|
"mysqladmin",
|
||||||
|
"ping",
|
||||||
|
"-h",
|
||||||
|
"localhost",
|
||||||
|
"-uroot",
|
||||||
|
"-p${SERVICE_PASSWORD_MYSQLROOT}",
|
||||||
|
]
|
||||||
|
interval: 5s
|
||||||
|
timeout: 20s
|
||||||
|
retries: 10
|
||||||
|
volumes:
|
||||||
|
- invoice-ninja-mysql-data:/var/lib/mysql
|
@ -4,7 +4,7 @@
|
|||||||
"version": "3.12.36"
|
"version": "3.12.36"
|
||||||
},
|
},
|
||||||
"v4": {
|
"v4": {
|
||||||
"version": "4.0.0-beta.225"
|
"version": "4.0.0-beta.226"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user