530
This commit is contained in:
@@ -0,0 +1,151 @@
|
||||
[KUBE](../README.md) / Backup
|
||||
|
||||
# Backup
|
||||
|
||||
- [Creation](#creation)
|
||||
- [Verification](#verification)
|
||||
- [Cleanup](#cleanup)
|
||||
- [LongTerm](#longterm)
|
||||
- [Commands](#commands)
|
||||
***
|
||||
|
||||
## Creation
|
||||
Directory structure of backups on the host machine: `<backup path>/<date>/<marker>`.
|
||||
- `<backup path>` – set by the `backupPath` parameter.
|
||||
- `<date>` – backup creation date in the format `YYYY-MM-DD`.
|
||||
- `<marker>` – a marker indicating the backup creation time in the format `HH-MM-SS`, with the first backup of the day named `<backupFirst>`.
|
||||
When the backup process starts, a directory `<backup path>/<date>/<marker>` is created (if it does not exist), where the backup files will be stored.
|
||||
|
||||
First, a backup of files is created depending on the `backupType` parameter:
|
||||
- `archive` – all subdirectories from `vhostsPath` are packed individually into separate archives named `<directory>.tar.gz`.
|
||||
- `rsync` – backup of the `vhostsPath` directory contents using the `rSync` utility.
|
||||
|
||||
Then, in each subdirectory of `vhostsPath`, the file `www/wp-config.php` is searched for, and database connection parameters are read from it. After that, the database is exported to a file and packed into an archive named `<directory>.sql.tar.gz`.
|
||||
|
||||
Next, the backup is copied to an external storage using the `rSync` utility. Two types of external storage (`storageType`) are supported:
|
||||
- `rsync` – for full functionality, connection parameters `rRync` and `FTP` must be set.
|
||||
- `ssh` – for full functionality, connection parameters `SSH` must be set.
|
||||
|
||||
Backup directory structure on external storage: `<storage path>/<hostname>`. Set by the following parameters:
|
||||
- `storagePath` – general path parameter for external storage
|
||||
- `rsyncPath` – path parameter for `rSync`
|
||||
- `ftpPath` – path parameter for `FTP`
|
||||
- `sshPath` – path parameter for `SSH`
|
||||
|
||||
Example:
|
||||
```bash
|
||||
storagePath="/$hostname"
|
||||
rsyncPath="$storagePath"
|
||||
ftpPath="$storagePath"
|
||||
sshPath="/_storage$storagePath"
|
||||
```
|
||||
Inside `<storage path>/<hostname>`, the directory structure on external storage fully mirrors the structure of `<backup path>` on the host machine.
|
||||
***
|
||||
|
||||
## Verification
|
||||
There are two types of backup verification available: verifying the latest backup and verifying all backups created on the current day.
|
||||
|
||||
When verifying the latest backup, the system searches for the latest backup execution log (directory `logs/backup` in the script folder). The file name is used to check the elapsed time since the last backup creation (parameter `backupElapsedMax`). The log contains the backup creation directory. Then, a non-recursive scan of subdirectories and files in the backup directory `<backup path>/<date>/<marker>` is performed. All directories and `*.tar.gz` files are considered website file backups, while `*.sql.tar.gz` files are considered database backups. A comparison is made between website file backups and database backups, and any discrepancies are noted. Next, the archive file sizes are checked (the minimum allowable size is set by the parameter `backupFileSizeMin`).
|
||||
|
||||
The next step is verifying the backup on external storage. The presence of the same subdirectories and files (non-recursively) is checked:
|
||||
```bash
|
||||
<backup path>/<date>/<marker>/* --> <storage path>/<hostname>/<date>/<marker>/*
|
||||
```
|
||||
A non-recursive file size comparison is performed, and any discrepancies are noted.
|
||||
|
||||
When verifying backups created on the current day, the day's directories are first compared:
|
||||
```bash
|
||||
<backup path>/<date>/* --> <storage path>/<hostname>/<date>/*
|
||||
```
|
||||
Then, each subdirectory is compared as described above.
|
||||
***
|
||||
|
||||
## Cleanup
|
||||
Backups cleanup occurs once every 24 hours. It is configured using two parameters:
|
||||
- `backupDays` – the number of past days (excluding the current day) for storing backups on the host machine.
|
||||
- `storageDays` – the number of past days (excluding the current day) for storing backups on external storage.
|
||||
|
||||
Example:
|
||||
```bash
|
||||
<backupPath>/2025-05-20/
|
||||
<backupPath>/2025-05-10/
|
||||
<backupPath>/2025-05-05/
|
||||
<backupPath>/2025-05-01/
|
||||
```
|
||||
|
||||
When `backupDays=2` and run `2025-05-20` will remain:
|
||||
```bash
|
||||
<backupPath>/2025-05-20/
|
||||
<backupPath>/2025-05-10/
|
||||
<backupPath>/2025-05-05/
|
||||
```
|
||||
|
||||
If `backupDays=2` and run after `2025-05-20` will remain:
|
||||
```bash
|
||||
<backupPath>/2025-05-20/
|
||||
<backupPath>/2025-05-10/
|
||||
```
|
||||
***
|
||||
|
||||
## LongTerm
|
||||
The `backupLongTermDays` parameter is responsible for the number of days for a long-term backup.
|
||||
When the corresponding command, the following happens
|
||||
1. The contents of the long-term backups directory (`<backupPath>/_longterm`) are checked.
|
||||
2. All copies older than `backupLongTermDays` except the earliest one are deleted.
|
||||
3. If there are no backups younger than `backupLongTermDays`, the first backup for the last day available is moved:
|
||||
```bash
|
||||
<backupPath>/<last day>/<backupFirst> --> <backupPath>/_longterm/<last day>/<backupFirst>
|
||||
```
|
||||
***
|
||||
|
||||
## Commands
|
||||
|
||||
### `-b, --backup [option]`
|
||||
Backup files and database of one site or all sites. Options:
|
||||
- `archive` - backup all domains to archives
|
||||
- `rsync` - backup all domains using rSync
|
||||
- `<domain>` - backup domain to archives (e.g., `example.com`)
|
||||
|
||||
> [!NOTE]
|
||||
> The default value (`archive` or `rsync`) is set by the `backupType` variable in the configuration file `config.sh`.
|
||||
|
||||
Example:
|
||||
```bash
|
||||
sudo kube.sh -b
|
||||
sudo kube.sh -b archive
|
||||
sudo kube.sh -b example.com
|
||||
```
|
||||
|
||||
Directory structure of backups: `<backupPath>/<date>/<marker>`
|
||||
- `<date>` - Date format `YYYY-MM-DD` (e.g., `2025-05-20`)
|
||||
- `<marker>` - First backup for day: `<backupFirst>` (`_first`), all next in time format `HH-MM-SS` (e.g., `09-30-55`)
|
||||
|
||||
Backup options:
|
||||
- `archive` - creates 2 archives and copies the `.conf` file for all sites + copies file `map.conf`:
|
||||
- `<backupPath>/<date>/<marker>/<domain*>.tar.gz`
|
||||
- `<backupPath>/<date>/<marker>/<domain*>.sql.tar.gz`
|
||||
- `<backupPath>/<date>/<marker>/<domain*>.conf`
|
||||
- `<backupPath>/<date>/<marker>/map.conf`
|
||||
- `rsync` - copies the `vhostsPath` virtual hosts folders, creates database archives and copied and database archives are created and copies `.conf` file for all sites + copies file `map.conf`:
|
||||
- `<backupPath>/<date>/<marker>/<domain*>`
|
||||
- `<backupPath>/<date>/<marker>/<domain*>.sql.tar.gz`
|
||||
- `<backupPath>/<date>/<marker>/<domain*>.conf`
|
||||
- `<backupPath>/<date>/<marker>/map.conf`
|
||||
- `domain` - creates 2 archives and copies the `.conf` file for the site:
|
||||
- `<backupPath>/<date>/<marker>/<domain>.tar.gz`
|
||||
- `<backupPath>/<date>/<marker>/<domain>.sql.tar.gz`
|
||||
- `<backupPath>/<date>/<marker>/<domain>.conf`
|
||||
|
||||
Example:
|
||||
```bash
|
||||
/backup/2025-05-21/08-00-00/example.com
|
||||
/backup/2025-05-21/08-00-00/example.com.conf
|
||||
/backup/2025-05-21/08-00-00/example.com.sql.tar.gz
|
||||
/backup/2025-05-21/_first/example.com
|
||||
/backup/2025-05-21/_first/example.com.conf
|
||||
/backup/2025-05-21/_first/example.com.sql.tar.gz
|
||||
/backup/2025-05-21/_first/map.conf
|
||||
/backup/2025-05-21/12-12-12/example.com.conf
|
||||
/backup/2025-05-20/12-12-12/example.com.tar.gz
|
||||
/backup/2025-05-20/12-12-12/example.com.sql.tar.gz
|
||||
```
|
||||
@@ -0,0 +1,22 @@
|
||||
[KUBE](../README.md) / CRON
|
||||
|
||||
# CRON
|
||||
|
||||
> Task management in CRON for scripts
|
||||
|
||||
## Commands
|
||||
|
||||
### `--cron <action>`
|
||||
|
||||
Working with CRON:
|
||||
- `add` - Adding jobs to CRON
|
||||
- `remove` - Removing jobs from CRON
|
||||
- `clean` - Clearing jobs of this script from CRON
|
||||
- `list` - Get list tasks for ROOT (default)
|
||||
|
||||
Example:
|
||||
```bash
|
||||
sudo kube.sh --cron
|
||||
sudo kube.sh --cron add
|
||||
sudo kube.sh --cron clean
|
||||
```
|
||||
@@ -0,0 +1,21 @@
|
||||
[KUBE](../README.md) / File structure
|
||||
|
||||
# File structure
|
||||
|
||||
- `assets/` - Supporting materials for infrastructure deployment
|
||||
- `assets/vhost.default/` - Template for vhosts without Wordpress (If there is)
|
||||
- `assets/vhost.wordpress/` - Template for vhosts with Wordpress (If there is)
|
||||
- `assets/yaml/*` - YAML templates for k3s
|
||||
- `assets/domains.list` - List of domains for Wordpress deployment
|
||||
- `assets/php.ini` - PHP settings file for OpenLiteSpeed
|
||||
- `assets/vhost.default.tar.gz` - Default packaged image of the site
|
||||
- `assets/vhost.wordpress.tar.gz` - Packaged Wordpress image
|
||||
- `assets/*.template` - Templates of files
|
||||
- `backups/` - Backup directory (default)
|
||||
- `data/` - Directory with service data for script
|
||||
- `docs/` - Directory with documents
|
||||
- `libs/` - Directory with function libraries
|
||||
- `logs/` - Directory with journals
|
||||
- `config.sh.default` - Settings script (example)
|
||||
- `kube.sh` - Executable script
|
||||
- `README.md` - Reference Guide
|
||||
@@ -0,0 +1,14 @@
|
||||
[KUBE](../README.md) / Install
|
||||
|
||||
# Install
|
||||
|
||||
> Scenarios for fully deploying the infrastructure for full operation. Install APK, update ipset/iptables, install kubernetes, create namespaces, apply yaml-files ...
|
||||
|
||||
## Commands
|
||||
|
||||
### `--install`
|
||||
|
||||
Example:
|
||||
```bash
|
||||
sudo kube.sh --install
|
||||
```
|
||||
@@ -0,0 +1,44 @@
|
||||
[KUBE](../README.md) / k3s
|
||||
|
||||
# k3s
|
||||
|
||||
## Resources
|
||||
|
||||
- [MariaDB](resources/mariadb.md)
|
||||
- [Redis](resources/redis.md)
|
||||
- [OpenLiteSpeed](resources/openlitespeed.md)
|
||||
- [Postfix](resources/postfix.md)
|
||||
- [Transfer](resources/transfer.md)
|
||||
|
||||
## Commands
|
||||
|
||||
### `-k, --k3s [option]`
|
||||
Options:
|
||||
- `create` - Create all resources
|
||||
- `clean` - Remove all resources
|
||||
- `status` - Status about a k3s resources
|
||||
- `info` - Detail about a k3s resources
|
||||
- `version` - Version info
|
||||
- `pod` - Get resources types of Pod
|
||||
- `pv` - Get resources types of PersistentVolume (PV)
|
||||
- `pvc` - Get resources types of PersistentVolumeClaim (PVC)
|
||||
- `service` - Get resources types of Service
|
||||
- `ing` - Get resources types of Ingress
|
||||
- `rs` - Get resources types of ReplicaSet
|
||||
- `sts` - Get resources types of StatefulSet
|
||||
- `deploy` - Get resources types of Deployment
|
||||
- `secret` - Get resources types of Secret
|
||||
- `cm` - Get resources types of ConfigMap
|
||||
- `ds` - Get resources types of DaemonSet
|
||||
- `job` - Get resources types of Job
|
||||
- `cj` - Get resources types of CronJob
|
||||
- `ep` - Get resources types of Endpoint
|
||||
- `nodes` - Get resources types of Node
|
||||
- `cs` - Get resources types of ComponentStatuses
|
||||
|
||||
Example:
|
||||
```bash
|
||||
sudo kube.sh -k status
|
||||
sudo kube.sh -k pod
|
||||
sudo kube.sh -k
|
||||
```
|
||||
@@ -0,0 +1,38 @@
|
||||
[KUBE](../README.md) / Log
|
||||
|
||||
# Log
|
||||
|
||||
> Opening the logs in the pods.
|
||||
|
||||
## Commands
|
||||
|
||||
### `--log`
|
||||
|
||||
> [!NOTE]
|
||||
> Standard kubectl parameters for logs can be added, for example:
|
||||
> `-f`: logs should be streamed<br>
|
||||
> `--previous`: print the logs for the previous instance of the container in a pod if it exists.
|
||||
|
||||
Example:
|
||||
```bash
|
||||
sudo kube.sh --log
|
||||
sudo kube.sh --log -f --tail=30
|
||||
```
|
||||
|
||||
Examples of responses:
|
||||
```bash
|
||||
🔹Log
|
||||
1: mariadb-master-0 [Running]
|
||||
2: mariadb-slave-0 [Running]
|
||||
3: openlitespeed-0 [Running]
|
||||
4: openlitespeed-1 [Running]
|
||||
5: postfix-78c47b95f6-42jcq [Running]
|
||||
6: redis-0 [Running]
|
||||
7: redis-1 [Running]
|
||||
8: redis-2 [Running]
|
||||
9: redis-sentinel-0 [Running]
|
||||
10: redis-sentinel-1 [Running]
|
||||
11: redis-sentinel-2 [Running]
|
||||
12: worker-6cd4bdb6b8-c6f5d [Running]
|
||||
Specify the pod number [0]:
|
||||
```
|
||||
@@ -0,0 +1,286 @@
|
||||
[KUBE](../README.md) / Mail server
|
||||
|
||||
# Mail server
|
||||
|
||||
## Template of zone
|
||||
```zone
|
||||
$TTL 300
|
||||
@ IN SOA ns1.mydns.example. dnsadmin.mydomain.com. (
|
||||
2025091001 ; serial
|
||||
3600 ; refresh
|
||||
900 ; retry
|
||||
1209600 ; expire
|
||||
300 ; minimum
|
||||
)
|
||||
IN NS ns1.mydns.example.
|
||||
IN NS ns2.mydns.example.
|
||||
|
||||
; ===== A/AAAA =====
|
||||
mta IN A {{PUBLIC_IPV4}}
|
||||
; mta IN AAAA {{PUBLIC_IPV6}} ; if available
|
||||
|
||||
; if desired, client sites can resolve to the same IP
|
||||
{{US1}} IN A {{PUBLIC_IPV4}}
|
||||
{{US2}} IN A {{PUBLIC_IPV4}}
|
||||
{{US3}} IN A {{PUBLIC_IPV4}}
|
||||
|
||||
; ===== MX =====
|
||||
; @ IN MX 10 mta.{{ROOT_DOMAIN}}. ; the root domain also accepts mail, if needed
|
||||
{{US1}} IN MX 10 mta.{{ROOT_DOMAIN}}.
|
||||
{{US2}} IN MX 10 mta.{{ROOT_DOMAIN}}.
|
||||
{{US3}} IN MX 10 mta.{{ROOT_DOMAIN}}.
|
||||
|
||||
; ===== SPF =====
|
||||
; @ IN TXT "v=spf1 mx ~all" ; if available
|
||||
mta IN TXT "v=spf1 a -all"
|
||||
{{US1}} IN TXT "v=spf1 mx ~all"
|
||||
{{US2}} IN TXT "v=spf1 mx ~all"
|
||||
{{US3}} IN TXT "v=spf1 mx ~all"
|
||||
|
||||
; ===== DKIM =====
|
||||
; For each customer domain, publish its own public key.
|
||||
; The selector can be shared (e.g., selector1); keys are different.
|
||||
selector1._domainkey.{{US1}} IN TXT "v=DKIM1; k=rsa; p={{PUBKEY_US1}}"
|
||||
selector1._domainkey.{{US2}} IN TXT "v=DKIM1; k=rsa; p={{PUBKEY_US2}}"
|
||||
selector1._domainkey.{{US3}} IN TXT "v=DKIM1; k=rsa; p={{PUBKEY_US3}}"
|
||||
|
||||
; ===== DMARC =====
|
||||
; Initially p=none to collect reports without impacting delivery.
|
||||
_dmarc.{{US1}} IN TXT "v=DMARC1; p=none; adkim=r; aspf=r; rua=mailto:{{DMARC_AGG}}; ruf=mailto:{{DMARC_FOR}}"
|
||||
_dmarc.{{US2}} IN TXT "v=DMARC1; p=none; adkim=r; aspf=r; rua=mailto:{{DMARC_AGG}}; ruf=mailto:{{DMARC_FOR}}"
|
||||
_dmarc.{{US3}} IN TXT "v=DMARC1; p=none; adkim=r; aspf=r; rua=mailto:{{DMARC_AGG}}; ruf=mailto:{{DMARC_FOR}}"
|
||||
; It is recommended to set DMARC on the root domain to cover ALL subdomains with a single policy.
|
||||
; _dmarc IN TXT "v=DMARC1; p=quarantine; sp=quarantine; adkim=r; aspf=r; rua=mailto:{{DMARC_AGG}}; ruf=mailto:{{DMARC_FOR}}"
|
||||
; (if test mode first — replace p=none, sp=none)
|
||||
|
||||
; ===== Additionally (optional but useful) =====
|
||||
; MTA-STS (if to implement)
|
||||
;_mta-sts IN TXT "v=STSv1; id=2025-09-10"
|
||||
;_smtp._tls IN TXT "v=TLSRPTv1; rua=mailto:tlsrpt@{{ROOT_DOMAIN}}"
|
||||
;autoconfig IN CNAME autoconfig.mailhost.example. ; for client autoconfiguration
|
||||
;autodiscover IN CNAME autodiscover.mailhost.example.
|
||||
```
|
||||
|
||||
```zone
|
||||
; ===== PTR =====
|
||||
{{PUBLIC_IPV4}} → mta.{{ROOT_DOMAIN}}
|
||||
```
|
||||
|
||||
Check: Postfix HELO/EHLO = mta.`{{ROOT_DOMAIN}}`
|
||||
|
||||
## Example
|
||||
`{{ROOT_DOMAIN}}` → krumax.cz \
|
||||
`{{PUBLIC_IPV4}}` → 31.31.73.67 \
|
||||
`{{US1}}`/`{{US2}}`/`{{US3}}` → us1 / us2 / us3 \
|
||||
`{{PUBKEY_US1}}`/`{{PUBKEY_US2}}`/`{{PUBKEY_US3}}` → DKIM public keys (only the content after `p=`, in a single line) \
|
||||
`{{DMARC_AGG}}`/`{{DMARC_FOR}}` → Addresses for DMARC reports (for example, dmarc@krumax.cz)
|
||||
|
||||
```zone
|
||||
$TTL 300
|
||||
|
||||
; ===== A =====
|
||||
mta IN A 31.31.73.67
|
||||
us1 IN A 31.31.73.67
|
||||
us2 IN A 31.31.73.67
|
||||
us3 IN A 31.31.73.67
|
||||
|
||||
; ===== MX =====
|
||||
us1 IN MX 10 mta.krumax.cz.
|
||||
us2 IN MX 10 mta.krumax.cz.
|
||||
us3 IN MX 10 mta.krumax.cz.
|
||||
|
||||
; ===== SPF =====
|
||||
mta IN TXT "v=spf1 a -all"
|
||||
us1 IN TXT "v=spf1 mx ~all"
|
||||
us2 IN TXT "v=spf1 mx ~all"
|
||||
us3 IN TXT "v=spf1 mx ~all"
|
||||
|
||||
; ===== DKIM =====
|
||||
selector1._domainkey.us1 IN TXT "v=DKIM1; k=rsa; p=MIIBI...(us1)"
|
||||
selector1._domainkey.us2 IN TXT "v=DKIM1; k=rsa; p=MIIBI...(us2)"
|
||||
selector1._domainkey.us3 IN TXT "v=DKIM1; k=rsa; p=MIIBI...(us3)"
|
||||
|
||||
; ===== DMARC =====
|
||||
_dmarc.us1 IN TXT "v=DMARC1; p=none; adkim=r; aspf=r; rua=mailto:dmarc@krumax.cz; ruf=mailto:dmarc@krumax.cz"
|
||||
_dmarc.us2 IN TXT "v=DMARC1; p=none; adkim=r; aspf=r; rua=mailto:dmarc@krumax.cz; ruf=mailto:dmarc@krumax.cz"
|
||||
_dmarc.us3 IN TXT "v=DMARC1; p=none; adkim=r; aspf=r; rua=mailto:dmarc@krumax.cz; ruf=mailto:dmarc@krumax.cz"
|
||||
```
|
||||
|
||||
```zone
|
||||
; ===== PTR =====
|
||||
31.31.73.67 → mta.krumax.cz
|
||||
```
|
||||
|
||||
|
||||
## Example of adding a new domain in Postfix
|
||||
1. Adding the domain and generating DKIM
|
||||
```bash
|
||||
sudo kube.sh postfix add us2.krumax.cz
|
||||
```
|
||||
2. Retrieving DKIM
|
||||
```bash
|
||||
sudo kube.sh postfix dkim us2.krumax.cz
|
||||
```
|
||||
3. Adding DNS records:
|
||||
```zone
|
||||
us2 IN A 31.31.73.67
|
||||
us2 IN MX 10 mta.krumax.cz.
|
||||
selector1._domainkey.us2 IN TXT "v=DKIM1; k=rsa; p=MIIBI...(from step 2)"
|
||||
_dmarc.us2 IN TXT "v=DMARC1; p=none; adkim=r; aspf=r; rua=mailto:dmarc@krumax.cz; ruf=mailto:dmarc@krumax.cz"
|
||||
```
|
||||
|
||||
|
||||
## Send mail in PHP.
|
||||
Create file for test send mail `send-mail.php`
|
||||
```php
|
||||
<?
|
||||
mb_internal_encoding('UTF-8');
|
||||
$to = 'maksym.krugol@wedos.org';
|
||||
$toName = 'Maksym Krugol';
|
||||
$from = 'no-reply@us1.krumax.cz';
|
||||
$fromName = 'Support team US1';
|
||||
$return = 'bounce@us1.krumax.cz';
|
||||
$subject = mb_encode_mimeheader('Test delivery (PHP)', 'UTF-8', 'B', "\r\n");
|
||||
$bodyText = "Hi! Test with PHP.";
|
||||
$bodyQP = quoted_printable_encode($bodyText);
|
||||
$headers = [
|
||||
"From: $fromName <$from>",
|
||||
"Reply-To: $from",
|
||||
"Return-Path: $return",
|
||||
"Date: " . date('r'),
|
||||
"Message-ID: <" . time() . "." . bin2hex(random_bytes(6)) . "@" . $hostname . ">",
|
||||
"MIME-Version: 1.0",
|
||||
"Content-Type: text/plain; charset=UTF-8",
|
||||
"Content-Transfer-Encoding: quoted-printable",
|
||||
"List-Unsubscribe: <mailto:unsubscribe@us1.krumax.cz?subject=unsubscribe>, <https://us1.krumax.cz/unsubscribe/".rawurlencode('maksym.krugol@wedos.org').">",
|
||||
];
|
||||
$headersStr = implode("\r\n", $headers);
|
||||
|
||||
$status = mail("$toName <$to>", $subject, $bodyQP, $headersStr, "-f$return");
|
||||
echo $status ? "Success\n" : "Failed\n";
|
||||
```
|
||||
|
||||
|
||||
## Send mail in Wordpress.
|
||||
1. Add Wordpress plugin `/wp-content/mu-plugins/smtp.php`
|
||||
```php
|
||||
<?php
|
||||
// For 25 port (without TLS/login)
|
||||
add_action('phpmailer_init', function ($phpmailer) {
|
||||
$phpmailer->isSMTP();
|
||||
$phpmailer->XMailer = 'krumaxMailer 1.0';
|
||||
$phpmailer->Host = 'mta.krumax.cz';
|
||||
$phpmailer->Port = 25;
|
||||
$phpmailer->SMTPAuth = false;
|
||||
$phpmailer->SMTPSecure = '';
|
||||
$phpmailer->SMTPAutoTLS = false;
|
||||
$phpmailer->From = 'no-reply@us1.krumax.cz';
|
||||
// $phpmailer->FromName = 'Support team US1';
|
||||
// $phpmailer->Hostname = 'us1.krumax.cz';
|
||||
// $phpmailer->Encoding = 'quoted-printable';
|
||||
// $phpmailer->Sender = 'bounce@us1.krumax.cz';
|
||||
// $phpmailer->Timeout = 15;
|
||||
});
|
||||
```
|
||||
```php
|
||||
<?php
|
||||
// For 587 port (with TLS/login)
|
||||
add_action('phpmailer_init', function ($phpmailer) {
|
||||
$phpmailer->isSMTP();
|
||||
$phpmailer->XMailer = 'krumaxMailer 1.0';
|
||||
$phpmailer->Host = 'mta.krumax.cz';
|
||||
$phpmailer->Port = 587;
|
||||
$phpmailer->Username = 'postmaster@us1.krumax.cz';
|
||||
$phpmailer->Password = 'qwerty';
|
||||
$phpmailer->SMTPAuth = true;
|
||||
$phpmailer->SMTPSecure = 'tls';
|
||||
$phpmailer->SMTPAutoTLS = true;
|
||||
$phpmailer->SMTPOptions = [
|
||||
'ssl' => [
|
||||
'allow_self_signed' => true,
|
||||
],
|
||||
];
|
||||
$phpmailer->From = 'no-reply@us1.krumax.cz';
|
||||
// $phpmailer->FromName = 'Support team US1';
|
||||
// $phpmailer->Hostname = 'us1.krumax.cz';
|
||||
// $phpmailer->Encoding = 'quoted-printable';
|
||||
// $phpmailer->Sender = 'bounce@us1.krumax.cz';
|
||||
// $phpmailer->Timeout = 15;
|
||||
});
|
||||
```
|
||||
2. Create file for test send mail `/send-mail.php`
|
||||
```php
|
||||
<?php
|
||||
require_once 'wp-load.php';
|
||||
|
||||
$domain = "us1.krumax.cz";
|
||||
$to = "maksym.krugol@wedos.org";
|
||||
$toName = "Maksym Krugol";
|
||||
$subject = "Test delivery (Wordpress)";
|
||||
$message = "Hi! Test with Wordpress.";
|
||||
$headers = [
|
||||
"List-Unsubscribe: <mailto:unsubscribe@{$domain}?subject=unsubscribe>, <https://{$domain}/unsubscribe/{$to}>"
|
||||
];
|
||||
|
||||
if (wp_mail("$toName <{$to}>", $subject, $message, $headers)) {
|
||||
echo "Success";
|
||||
} else {
|
||||
echo "Failed";
|
||||
}
|
||||
```
|
||||
3. Open URL http://us1.krumax.cz/send-mail.php
|
||||
|
||||
|
||||
## Send mail from pod in k3s (use Postfix).
|
||||
1. Install postfix: `apt-get install -y postfix`
|
||||
2. Set config:
|
||||
```bash
|
||||
postconf -e 'myhostname = mta.krumax.cz'
|
||||
postconf -e 'mydomain = us1.krumax.cz'
|
||||
postconf -e 'myorigin = $mydomain'
|
||||
```
|
||||
3. Create file `test.mail`:
|
||||
```
|
||||
From: Support team US1 <no-reply@us1.krumax.cz>
|
||||
To: Maksym Krugol <maksym.krugol@wedos.org>
|
||||
Subject: Test delivery (postfix)
|
||||
Date: Wed, 17 Sep 2025 10:53:13 +0200
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: quoted-printable
|
||||
|
||||
Hi! Test with /usr/sbin/sendmail.
|
||||
```
|
||||
4. Send mail: `sendmail -v -oi -t -f 'no-reply@us1.krumax.cz' < test.mail`
|
||||
|
||||
## Send mail from pod in k3s (use msmtp).
|
||||
1. Install msmtp: `apt-get install -y msmtp msmtp-mta ca-certificates`
|
||||
2. Set config `/etc/msmtprc`:
|
||||
```
|
||||
defaults
|
||||
auth on
|
||||
tls on
|
||||
tls_starttls on
|
||||
tls_trust_file /etc/ssl/certs/ca-certificates.crt
|
||||
logfile /var/log/msmtp.log
|
||||
|
||||
account default
|
||||
host mta.krumax.cz
|
||||
port 587
|
||||
from no-reply@us1.krumax.cz
|
||||
user postmaster@us1.krumax.cz
|
||||
password qwerty
|
||||
```
|
||||
3. Create file `test.mail`:
|
||||
```
|
||||
From: Support team US1 <no-reply@us1.krumax.cz>
|
||||
To: Maksym Krugol <maksym.krugol@wedos.org>
|
||||
Subject: Test delivery (msmtp)
|
||||
Date: Wed, 17 Sep 2025 10:53:13 +0200
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: quoted-printable
|
||||
|
||||
Hi! Test with msmtp/sendmail.
|
||||
```
|
||||
4. Send mail: `sendmail -v -oi -t -f 'no-reply@us1.krumax.cz' < test.mail`
|
||||
@@ -0,0 +1,47 @@
|
||||
|
||||
|
||||
|
||||
- [Getting started](#getting-started)
|
||||
- [Site Creation](#site-creation)
|
||||
- [Wordpress configuration](#wordpress-configuration)
|
||||
- [Transfer](docs/transfer.md)
|
||||
|
||||
> [!NOTE]
|
||||
> For `rSync` to work, the password must be in a file, with permissions `600` and owner `root`.
|
||||
|
||||
|
||||
***
|
||||
### `--info [resource]`
|
||||
|
||||
Extensive information on the status of various resources is provided:
|
||||
- `[all]` - Info from all resources
|
||||
- `k3s` - Info from all resources `k3s`
|
||||
- `mariadb` - Info from `MariaDB` (master-slave replica)
|
||||
- `redis` - Info from `Redis` and `RedisSentinel`
|
||||
- `openlitespeed` - Info from `OpenLiteSpeed`
|
||||
|
||||
Example:
|
||||
```bash
|
||||
sudo kube.sh --info
|
||||
sudo kube.sh --info all
|
||||
sudo kube.sh --info mariadb
|
||||
```
|
||||
|
||||
|
||||
|
||||
---
|
||||
***
|
||||
### `--version`
|
||||
|
||||
Collecting information about version system components:
|
||||
|
||||
- Kubernetes (k3s)
|
||||
- MariaDB
|
||||
- Redis
|
||||
- OpenLiteSpeed
|
||||
|
||||
Example:
|
||||
```bash
|
||||
sudo kube.sh --version
|
||||
```
|
||||
---
|
||||
@@ -0,0 +1,129 @@
|
||||
[KUBE](../README.md) / Options
|
||||
|
||||
# Options
|
||||
|
||||
>Options in script `config.sh`
|
||||
|
||||
- `assetsPath` - Directory assets (for script)
|
||||
- `dataPath` - Directory data (for script)
|
||||
- `namespace` - Default kubernetes namespace
|
||||
- `hostname` - Hostname server
|
||||
- `basePath` - Base path for all resources
|
||||
- `vhostsPath` - Directory for vhosts
|
||||
- `domainsList` - File with domains list
|
||||
***
|
||||
|
||||
- `k3sCmd` - Path to k3s on host
|
||||
- `k3sReadyRetries` - Number of attempts to check k3s readiness
|
||||
- `k3sReadySleep` - Pause between attempts
|
||||
***
|
||||
|
||||
- `redisKube` - Redis identifier in k3s
|
||||
- `redisSentinelKube` - Redis Sentinel identifier in k3s
|
||||
- `redisYaml` - Path to file template YAML for Redis
|
||||
- `redisPath` - Directory for Redis configuration
|
||||
- `redisFileUsersAcl` - Filename for users in Redis
|
||||
- `redisRootPass` - Redis password
|
||||
***
|
||||
|
||||
- `mariadbKube` - MariaDB identifier in k3s
|
||||
- `mariadbMasterKube` - MariaDB Master node identifier in k3s
|
||||
- `mariadbSlaveKube` - MariaDB Slave node identifier in k3s
|
||||
- `mariadbYaml` - Path to file template YAML for MariaDB
|
||||
- `mariadbMasterPath` - Directory for MariaDB Master node (replica)
|
||||
- `mariadbSlavePath` - Directory for MariaDB Slave node (replica)
|
||||
- `mariadbRootPass` - MariaDB root password
|
||||
***
|
||||
|
||||
- `openlitespeedKube` - Openlitespeed identifier in k3s
|
||||
- `openlitespeedYaml` - Path to file template YAML for OpenLiteSpeed
|
||||
- `openlitespeedPath` - Directory for OpenLiteSpeed configuration
|
||||
- `openlitespeedAdminPath` - Directory for OpenLiteSpeed Admin configuration
|
||||
- `openlitespeedConfigFile` - OpenLiteSpeed configuration file
|
||||
- `openlitespeedVhostsPath` - Directory for vhosts configuration files
|
||||
- `openlitespeedAdminPass` - OpenLiteSpeed admin panel password
|
||||
***
|
||||
|
||||
- `postfixKube` - Postfix identifier in k3s
|
||||
- `postfixYaml` - Path to file template YAML for Postfix
|
||||
- `postfixPath` - Directory for Postfix
|
||||
- `postfixConfigPath` - Directory for Postfix configuration
|
||||
- `postfixDkimPath` - Directory for Postfix DKIM
|
||||
- `postfixTlsCrtFile` - File TLS certificate (if not specified, a self-signed one will be generated)
|
||||
- `postfixTlsKey` - Fil TLS key (if not specified, a self-signed one will be generated)
|
||||
- `postfixHost` - Host for MTA
|
||||
- `postfixPostmaster` - Postmaster (email) for MTA
|
||||
- `postfixDefaultRealm` - Default realm for MTA
|
||||
- `postfixDkimSelector` - Selector DKIM
|
||||
- `postfixDomainsFile` - File of Domains list
|
||||
- `postfixAliasesFile` - File of Aliases list
|
||||
- `postfixSendersFile` - File of Senders list
|
||||
- `postfixIp` - IP address for MTA
|
||||
***
|
||||
|
||||
- `workerKube` - Worker identifier in k3s
|
||||
- `workerYaml` - Path to file template YAML for Worker
|
||||
- `workerPath` - Directory for Worker
|
||||
- `workerAgentPath` - Path to directory with agent script
|
||||
- `workerTasksPath` - Path to directory with tasks-files
|
||||
- `workerFilesPath` - Path to directory with loading files
|
||||
- `workerName` - Worker name
|
||||
- `workerApiUrl` - URL to API
|
||||
- `workerApiGettingPause` - Pause between requests for a new task
|
||||
- `workerApiSendingPause` - Pause between sending task statuses
|
||||
***
|
||||
|
||||
- `logPath` - Directory journals (for script)
|
||||
- `logFile` - Log file name format
|
||||
***
|
||||
|
||||
- `backupPath` - Directory for backups on current host
|
||||
- `backupLogPath` - Directory for backups logs
|
||||
- `backupType` - Backup Type (rsync, archive)
|
||||
- `backupFirst` - Directory name for the first backup of the day
|
||||
- `backupDays` - Number of last days of backup storage (excluding current day backups)
|
||||
- `backupMask` - A mask for selecting backup storage day directories (must match `scriptDate`)
|
||||
- `backupLongTermPath` - Directory for long-term backups
|
||||
- `backupLongTermDays` - Minimum number of days for a long-term backup.
|
||||
- `backupExcludeFile` - List of files and directories that were excluded during backup
|
||||
- `backupExcludeList` - List of files and directories that should be excluded during backup
|
||||
- `backupFileSizeMin` - Minimum archive size during verification (bytes)
|
||||
- `backupElapsedMax` - Maximum time elapsed since the last backup was created (min)
|
||||
***
|
||||
|
||||
- `storagePath` - Directory for backups on external storage
|
||||
- `storageType` - Directory external storage (rsync, ssh)
|
||||
- `storageDays` - Number of last days of backup storage on external storage (excluding current day backups)
|
||||
***
|
||||
|
||||
- `rsyncUri` - URI (format: `user@server[:port][/path]`) (for rSync)
|
||||
- `rsyncPassFile` - File with password (for rSync)
|
||||
- `rsyncPath` - Directory for backups on external storage (for rSync)
|
||||
***
|
||||
|
||||
- `ftpHost` - Hostname (for FTP)
|
||||
- `ftpPort` - Port (for FTP)
|
||||
- `ftpUser` - Username (for FTP)
|
||||
- `ftpPass` - Password (for FTP)
|
||||
- `ftpPath` - Directory for backups on external storage (for FTP)
|
||||
***
|
||||
|
||||
- `sshHost` - Hostname (for SSH)
|
||||
- `sshUser` - Username (for SSH)
|
||||
- `sshKeyFile` - Public key file (for SSH)
|
||||
- `sshPath` - Directory for backups on external storage (for SSH)
|
||||
***
|
||||
|
||||
- `reportFile` - Filename for reports
|
||||
- `reportMask` - Report filename mask
|
||||
***
|
||||
|
||||
- `mailTo` - Email for sending reports (to)
|
||||
- `mailFrom` - Email for sending reports (from)
|
||||
***
|
||||
|
||||
- `cronJobs` - Jobs for adding to CRON
|
||||
***
|
||||
|
||||
- `diskUsedSpaceLimit` - Limiting the disk space used (%)
|
||||
***
|
||||
@@ -0,0 +1,167 @@
|
||||
[KUBE](../../README.md) / [k3s](../k3s.md) / MariaDB
|
||||
|
||||
# Resource MariaDB
|
||||
|
||||
> [!NOTE]
|
||||
> A replica of two pods `mariadb-master` and `mariadb-slave` is created. Each of the pods has a separate storage. When configuring the connection, the host is specified: `mariadb-master`.
|
||||
|
||||
- [Install](#install)
|
||||
- [Remove](#remove)
|
||||
- [Status](#status)
|
||||
- [Info](#info)
|
||||
- [Version](#version)
|
||||
- [Database list](#database-list)
|
||||
- [User list](#user-list)
|
||||
- [Dump](#dump)
|
||||
***
|
||||
|
||||
## Install
|
||||
|
||||
### Processing
|
||||
1. Preparation.
|
||||
- Recreate the secret with the passwords `root-password` and `replication-password`.
|
||||
|
||||
2. Creation.
|
||||
- Prepare the import file.
|
||||
- Import the YAML.
|
||||
|
||||
3. Post-processing.
|
||||
- Initialize the replica.
|
||||
|
||||
Command:
|
||||
```bash
|
||||
sudo kube.sh --mariadb install
|
||||
```
|
||||
|
||||
Example of log:
|
||||
```bash
|
||||
🔹[K3S] Resource add | mariadb
|
||||
✅[MariaDB] | Delete old Secret: OK
|
||||
✅[MariaDB] | Create new Secret: OK
|
||||
🔹[MariaDB] Preparing /app/kube/assets/yaml/mariadb.yaml
|
||||
🔹[K3S] Applying YAML /app/kube/data/yaml/mariadb.yaml
|
||||
💡[K3S] Waiting for pods to be ready... | 2 not ready
|
||||
💡[K3S] Waiting for pods to be ready... | 1 not ready
|
||||
✅[MariaDB] Applied /app/kube/data/yaml/mariadb.yaml
|
||||
🔹[MariaDB] Replica initialization...
|
||||
✅[MariaDB] Master node | Create replication user: OK
|
||||
✅[MariaDB] Master node | Status: OK
|
||||
✅[MariaDB] Slave node | Change master: OK
|
||||
✅[MariaDB] Slave node | Status: OK | Delay 0s
|
||||
✅[MariaDB] Replica initialization completed successfully
|
||||
```
|
||||
***
|
||||
|
||||
## Remove
|
||||
|
||||
Command:
|
||||
```bash
|
||||
sudo kube.sh --mariadb remove
|
||||
```
|
||||
***
|
||||
|
||||
## Status
|
||||
|
||||
Command:
|
||||
```bash
|
||||
sudo kube.sh --mariadb status
|
||||
```
|
||||
|
||||
Example of log:
|
||||
```bash
|
||||
🔹[MariaDB] Status
|
||||
✅[MariaDB] Databases: 10 | Users: 10 | Size: 1.234 Gb
|
||||
✅[MariaDB] Master node | Running
|
||||
✅[MariaDB] Slave node | Running
|
||||
```
|
||||
***
|
||||
|
||||
## Info
|
||||
|
||||
Command:
|
||||
```bash
|
||||
sudo kube.sh --mariadb info
|
||||
```
|
||||
|
||||
Example of log:
|
||||
```bash
|
||||
🔹[MariaDB] Info
|
||||
🔹[MariaDB] Master node
|
||||
mysql-bin.000025 10341
|
||||
🔹[MariaDB] Slave node
|
||||
*************************** 1. row ***************************
|
||||
Slave_IO_State: Waiting for master to send event
|
||||
Master_Host: mariadb-master
|
||||
Master_User: replication_user
|
||||
Master_Port: 3306
|
||||
...
|
||||
```
|
||||
***
|
||||
|
||||
## Version
|
||||
|
||||
Command:
|
||||
```bash
|
||||
sudo kube.sh --mariadb version
|
||||
```
|
||||
|
||||
Example of log:
|
||||
```bash
|
||||
🔹[MariaDB] Version
|
||||
✅[MariaDB] Master node | mariadb from 11.7.2-MariaDB, client 15.2 for debian-linux-gnu (x86_64) using EditLine wrapper
|
||||
✅[MariaDB] Slave node | mariadb from 11.7.2-MariaDB, client 15.2 for debian-linux-gnu (x86_64) using EditLine wrapper
|
||||
```
|
||||
***
|
||||
|
||||
## Database list
|
||||
|
||||
> [!NOTE]
|
||||
> List of databases (except for service databases: `information_schema`, `performance_schema`, `mysql`, `sys`)
|
||||
|
||||
Command:
|
||||
```bash
|
||||
sudo kube.sh --mariadb database
|
||||
```
|
||||
|
||||
Example of log:
|
||||
```bash
|
||||
🔹[MariaDB] Database list
|
||||
us1_example_com
|
||||
us2_example_com
|
||||
us3_example_com
|
||||
```
|
||||
***
|
||||
|
||||
## User list
|
||||
|
||||
> [!NOTE]
|
||||
> List of users (except for service users `root`, `replication_user`)
|
||||
|
||||
Command:
|
||||
```bash
|
||||
sudo kube.sh --mariadb user
|
||||
```
|
||||
|
||||
Example of log:
|
||||
```bash
|
||||
🔹[MariaDB] User list
|
||||
us1_example_com
|
||||
us2_example_com
|
||||
us3_example_com
|
||||
```
|
||||
***
|
||||
|
||||
## Dump
|
||||
|
||||
Command:
|
||||
```bash
|
||||
sudo kube.sh --mariadb dump
|
||||
sudo kube.sh --mariadb dump dump.sql
|
||||
sudo kube.sh --mariadb dump dump.sql us1_example_com
|
||||
```
|
||||
|
||||
Example of log:
|
||||
```bash
|
||||
🔹[MariaDB] Dump
|
||||
✅[MariaDB] Dump: /app/kube/data/mariadb/2025-10-27_10-10-58.sql.tar.gz
|
||||
```
|
||||
@@ -0,0 +1,179 @@
|
||||
[KUBE](../../README.md) / [k3s](../k3s.md) / OpenLiteSpeed
|
||||
|
||||
# Resource OpenLiteSpeed
|
||||
|
||||
> [!NOTE]
|
||||
> Two (you can specify a different number) pods are created. They work simultaneously. If one pod fails, the second pod starts processing all requests until a replacement for the failed pod is brought up. When changes are made to the virtual host configuration, OpenLiteSpeed is restarted sequentially in all pods.
|
||||
>
|
||||
> The administration panel OpenLiteSpeed is available at an address:
|
||||
> - `<domain>:31080` (local and remote)
|
||||
> - `<server ip>:31080` (remote)
|
||||
> - `<node ip>:7080` (local, `<node ip>` can be found upon request: `kube.sh --info | grep 7080`)
|
||||
|
||||
- [Install](#install)
|
||||
- [Remove](#remove)
|
||||
- [Status](#status)
|
||||
- [Info](#info)
|
||||
- [Version](#version)
|
||||
- [Restart](#restart)
|
||||
- [Site list](#site-list)
|
||||
- [Site unlock](#site-unlock)
|
||||
- [Site lock](#site-lock)
|
||||
- [Config](#config-test)
|
||||
***
|
||||
|
||||
## Install
|
||||
|
||||
### Processing
|
||||
1. Creation.
|
||||
- Prepare the import file.
|
||||
- Import the YAML.
|
||||
|
||||
2. Post-processing.
|
||||
- Initialization.
|
||||
|
||||
Command:
|
||||
```bash
|
||||
sudo kube.sh --ols install
|
||||
```
|
||||
|
||||
Example of log:
|
||||
```bash
|
||||
🔹[OpenLiteSpeed] Install
|
||||
🔹[OpenLiteSpeed] Preparing /app/kube/assets/yaml/openlitespeed.yaml
|
||||
🔹[K3S] Applying YAML /app/kube/data/yaml/openlitespeed.yaml
|
||||
💡[K3S] Waiting for pods to be ready... | 1 not ready
|
||||
💡[K3S] Waiting for pods to be ready... | 1 not ready
|
||||
✅[OpenLiteSpeed] Applied /app/kube/data/yaml/openlitespeed.yaml
|
||||
🔹[OpenLiteSpeed] Initialization...
|
||||
🔹[OpenLiteSpeed] Authorization parameters updated
|
||||
service/traefik patched
|
||||
🔹[OpenLiteSpeed] Pod: openlitespeed-0 | Restart...
|
||||
🔹[OpenLiteSpeed] Pod: openlitespeed-1 | Restart...
|
||||
✅[OpenLiteSpeed] Initialization completed successfully
|
||||
```
|
||||
***
|
||||
|
||||
## Remove
|
||||
|
||||
Command:
|
||||
```bash
|
||||
sudo kube.sh --ols remove
|
||||
```
|
||||
***
|
||||
|
||||
## Status
|
||||
|
||||
Command:
|
||||
```bash
|
||||
sudo kube.sh --ols status
|
||||
```
|
||||
|
||||
Example of log:
|
||||
```bash
|
||||
🔹[OpenLiteSpeed] Status
|
||||
✅[OpenLiteSpeed] openlitespeed-0 | Running | PID 251
|
||||
✅[OpenLiteSpeed] openlitespeed-1 | Running | PID 216
|
||||
```
|
||||
***
|
||||
|
||||
## Info
|
||||
|
||||
Command:
|
||||
```bash
|
||||
sudo kube.sh --ols info
|
||||
```
|
||||
|
||||
Example of log:
|
||||
```bash
|
||||
🔹[OpenLiteSpeed] Info
|
||||
🔹[OpenLiteSpeed] openlitespeed-0
|
||||
litespeed is running with PID 251.
|
||||
🔹[OpenLiteSpeed] openlitespeed-1
|
||||
litespeed is running with PID 216.
|
||||
```
|
||||
***
|
||||
|
||||
## Version
|
||||
|
||||
Command:
|
||||
```bash
|
||||
sudo kube.sh --ols version
|
||||
```
|
||||
|
||||
Example of log:
|
||||
```bash
|
||||
🔹[OpenLiteSpeed] Version
|
||||
✅[OpenLiteSpeed] openlitespeed-0 | LiteSpeed/1.8.3 Open (BUILD built: Fri Feb 28 16:33:02 UTC 2025)
|
||||
✅[OpenLiteSpeed] openlitespeed-0 | PHP: 8.3.17
|
||||
✅[OpenLiteSpeed] openlitespeed-1 | LiteSpeed/1.8.3 Open (BUILD built: Fri Feb 28 16:33:02 UTC 2025)
|
||||
✅[OpenLiteSpeed] openlitespeed-1 | PHP: 8.3.17
|
||||
```
|
||||
***
|
||||
|
||||
## Restart
|
||||
|
||||
Command:
|
||||
```bash
|
||||
sudo kube.sh --ols restart
|
||||
```
|
||||
|
||||
Example of log:
|
||||
```bash
|
||||
🔹[OpenLiteSpeed] Restart
|
||||
🔹[OpenLiteSpeed] Pod: openlitespeed-0 | Restart...
|
||||
🔹[OpenLiteSpeed] Pod: openlitespeed-1 | Restart...
|
||||
```
|
||||
***
|
||||
|
||||
## Site list
|
||||
|
||||
Command:
|
||||
```bash
|
||||
sudo kube.sh --ols list [option]
|
||||
```
|
||||
|
||||
Options:
|
||||
- all - All sites (colored up/down) (default)
|
||||
- all - All sites
|
||||
- up - Unlocked sites
|
||||
- down - Locked sites
|
||||
|
||||
Example of log:
|
||||
```bash
|
||||
example1.com
|
||||
example2.com
|
||||
example3.com
|
||||
```
|
||||
***
|
||||
|
||||
## Site unlock
|
||||
|
||||
> [!NOTE]
|
||||
> Unlock domain (Resume site operation in OpenLiteSpeed).
|
||||
|
||||
Command:
|
||||
```bash
|
||||
sudo kube.sh --ols up <domain>
|
||||
```
|
||||
***
|
||||
|
||||
## Site lock
|
||||
|
||||
> [!NOTE]
|
||||
> Lock domain (Pause the site in OpenLiteSpeed).
|
||||
>
|
||||
> The OpenLiteSpeed page will be displayed with a 403 error when the domain is accessed.
|
||||
|
||||
Command:
|
||||
```bash
|
||||
sudo kube.sh --ols down <domain>
|
||||
```
|
||||
***
|
||||
|
||||
## Config test
|
||||
|
||||
Command:
|
||||
```bash
|
||||
sudo kube.sh --ols config
|
||||
```
|
||||
@@ -0,0 +1,121 @@
|
||||
[KUBE](../../README.md) / [k3s](../k3s.md) / Postfix
|
||||
|
||||
# Resource Postfix
|
||||
|
||||
- [Install](#install)
|
||||
- [Remove](#remove)
|
||||
- [Status](#status)
|
||||
- [Add domain](#add-domain-)
|
||||
- [Get DKIM key](#get-dkim-key-for-dns-record-domain-or-dkim-record-lists)
|
||||
- [Check DNS records](#check-dns-records-for--or-mta)
|
||||
- [Get template of DNS records](#get-template-of-dns-records)
|
||||
***
|
||||
|
||||
## Install
|
||||
|
||||
Command:
|
||||
```bash
|
||||
sudo kube.sh --postfix install
|
||||
```
|
||||
|
||||
Example of log:
|
||||
```bash
|
||||
🔹[Postfix] Install
|
||||
🔹[Postfix] Preparing /app/kube/assets/yaml/postfix.yaml
|
||||
🔹[K3S] Applying YAML /app/kube/data/yaml/postfix.yaml
|
||||
💡[K3S] Waiting for pods to be ready... | 1 not ready
|
||||
💡[K3S] Waiting for pods to be ready... | 1 not ready
|
||||
💡[K3S] Waiting for pods to be ready... | 1 not ready
|
||||
💡[K3S] Waiting for pods to be ready... | 1 not ready
|
||||
✅[Postfix] Applied /app/kube/data/yaml/postfix.yaml
|
||||
```
|
||||
***
|
||||
|
||||
## Remove
|
||||
|
||||
Command:
|
||||
```bash
|
||||
sudo kube.sh --postfix remove
|
||||
```
|
||||
***
|
||||
|
||||
## Status
|
||||
|
||||
> [!NOTE]
|
||||
> In progress...
|
||||
|
||||
Command:
|
||||
```bash
|
||||
sudo kube.sh --postfix status
|
||||
```
|
||||
|
||||
Example of log:
|
||||
```bash
|
||||
???
|
||||
```
|
||||
***
|
||||
|
||||
## Add domain <domain>
|
||||
|
||||
> [!NOTE]
|
||||
> In progress...
|
||||
|
||||
Command:
|
||||
```bash
|
||||
sudo kube.sh --postfix add <domain>
|
||||
```
|
||||
***
|
||||
|
||||
## Get DKIM key for DNS record domain or DKIM record lists
|
||||
|
||||
Command:
|
||||
```bash
|
||||
sudo ube.sh --postfix dkim [domain]
|
||||
```
|
||||
|
||||
Example of log:
|
||||
```bash
|
||||
[Postfix] DKIM key for DNS
|
||||
selector1._domainkey IN TXT ( "v=DKIM1; h=sha256; k=rsa; s=email; "
|
||||
"p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6rCyqEvQ1...FQIDAQAB" ) ; ----- DKIM key selector1 for krumax.cz
|
||||
```
|
||||
***
|
||||
|
||||
## Check DNS records for <domain> or MTA
|
||||
|
||||
Command:
|
||||
```bash
|
||||
sudo kube.sh --postfix dns [domain]
|
||||
```
|
||||
|
||||
Example of log:
|
||||
```bash
|
||||
🔹[Postfix] Check DNS records
|
||||
✅[Postfix] A record: mta.krumax.cz | 31.31.73.67
|
||||
✅[Postfix] SPF record: mta.krumax.cz | "v=spf1 a -all"
|
||||
✅[Postfix] PTR record: mta.krumax.cz | mta.krumax.cz.
|
||||
```
|
||||
***
|
||||
|
||||
## Get template of DNS records
|
||||
|
||||
Command:
|
||||
```
|
||||
sudo kube.sh --postfix template
|
||||
```
|
||||
|
||||
Example of log:
|
||||
```bash
|
||||
🔹[Postfix] Template
|
||||
🔹[Postfix] For MTA ==============
|
||||
🔹[Postfix] IN A 31.31.73.67
|
||||
🔹[Postfix] IN TXT v=spf1 a -all
|
||||
🔹[Postfix] PTR -> mta.krumax.cz
|
||||
|
||||
🔹[Postfix] For site =============
|
||||
🔹[Postfix] IN A 31.31.73.67
|
||||
🔹[Postfix] IN MX 10 mta.krumax.cz.
|
||||
🔹[Postfix] IN TXT v=spf1 mx ~all
|
||||
🔹[Postfix] IN TXT v=DKIM1; ...
|
||||
🔹[Postfix] IN TXT v=DMARC1; ...
|
||||
```
|
||||
@@ -0,0 +1,163 @@
|
||||
[KUBE](../../README.md) / [k3s](../k3s.md) / Redis
|
||||
|
||||
|
||||
# Resource Redis
|
||||
|
||||
> [!NOTE]
|
||||
> A replica of three pods is created: 1 master (`redis-0`) + 2 slaves (`redis-1`, `redis-2`). A cluster of three RedisSentinel is created to manage the replica. When configuring the connection, the host is specified: redis-0.redis.
|
||||
|
||||
> [!WARNING]
|
||||
> In the current configuration, when changing the RedisSentinel master node of the replica, there is no automatic change of connection to the new master node. Solution: adding HAProxy to automatically redirect requests to the current Redis master node.
|
||||
|
||||
- [Install](#install)
|
||||
- [Remove](#remove)
|
||||
- [Status](#status)
|
||||
- [Info](#info)
|
||||
- [Version](#version)
|
||||
- [User list](#user-list)
|
||||
***
|
||||
|
||||
## Install
|
||||
|
||||
### Processing
|
||||
1. Preparation.
|
||||
- Recreate the secret with the passwords `root-password`.
|
||||
|
||||
2. Creation.
|
||||
- Prepare the import file.
|
||||
- Import the YAML.
|
||||
|
||||
Command:
|
||||
```bash
|
||||
sudo kube.sh --redis install
|
||||
```
|
||||
|
||||
Example of log:
|
||||
```bash
|
||||
🔹[Redis] Install
|
||||
✅[Redis] Delete old Secret: OK
|
||||
✅[Redis] Create new Secret: OK
|
||||
🔹[Redis] Preparing /app/kube/assets/yaml/redis.yaml
|
||||
🔹[K3S] Applying YAML /app/kube/data/yaml/redis.yaml
|
||||
💡[K3S] Waiting for pods to be ready... | 2 not ready
|
||||
💡[K3S] Waiting for pods to be ready... | 1 not ready
|
||||
✅[Redis] Applied /app/kube/data/yaml/redis.yaml
|
||||
```
|
||||
***
|
||||
|
||||
## Remove
|
||||
|
||||
Command:
|
||||
```bash
|
||||
sudo kube.sh --redis remove
|
||||
```
|
||||
***
|
||||
|
||||
## Status
|
||||
|
||||
Command:
|
||||
```bash
|
||||
sudo kube.sh --redis status
|
||||
```
|
||||
|
||||
Example of log:
|
||||
```bash
|
||||
🔹[Redis] Status
|
||||
✅[Redis] redis-0 | Role: Master | Slaves: 2
|
||||
✅[Redis] redis-1 | Role: Slave | Master: redis-0.redis
|
||||
✅[Redis] redis-2 | Role: Slave | Master: redis-0.redis
|
||||
✅[RedisSentinel] redis-sentinel-0 | Master: mymaster [redis-0.redis:6379] | Slaves: 2 | Other sentinels: 2 | Quorum: 2
|
||||
✅[RedisSentinel] redis-sentinel-0 | Slave: 10.42.0.16:6379 [10.42.0.16:6379] | Master: redis-0.redis
|
||||
✅[RedisSentinel] redis-sentinel-0 | Slave: 10.42.0.14:6379 [10.42.0.14:6379] | Master: redis-0.redis
|
||||
✅[RedisSentinel] redis-sentinel-1 | Master: mymaster [redis-0.redis:6379] | Slaves: 2 | Other sentinels: 2 | Quorum: 2
|
||||
✅[RedisSentinel] redis-sentinel-1 | Slave: 10.42.0.16:6379 [10.42.0.16:6379] | Master: redis-0.redis
|
||||
✅[RedisSentinel] redis-sentinel-1 | Slave: 10.42.0.14:6379 [10.42.0.14:6379] | Master: redis-0.redis
|
||||
✅[RedisSentinel] redis-sentinel-2 | Master: mymaster [redis-0.redis:6379] | Slaves: 2 | Other sentinels: 2 | Quorum: 2
|
||||
✅[RedisSentinel] redis-sentinel-2 | Slave: 10.42.0.16:6379 [10.42.0.16:6379] | Master: redis-0.redis
|
||||
✅[RedisSentinel] redis-sentinel-2 | Slave: 10.42.0.14:6379 [10.42.0.14:6379] | Master: redis-0.redis
|
||||
```
|
||||
***
|
||||
|
||||
## Info
|
||||
|
||||
Command:
|
||||
```bash
|
||||
sudo kube.sh --redis info
|
||||
```
|
||||
|
||||
Example of log:
|
||||
```bash
|
||||
🔹[Redis] Info
|
||||
🔹[Redis] redis-0
|
||||
# Replication
|
||||
role:master
|
||||
connected_slaves:2
|
||||
slave0:ip=10.42.0.14,port=6379,state=online,offset=1092850,lag=0
|
||||
slave1:ip=10.42.0.16,port=6379,state=online,offset=1092714,lag=1
|
||||
...
|
||||
🔹[Redis] redis-1
|
||||
# Replication
|
||||
role:slave
|
||||
master_host:redis-0.redis
|
||||
master_port:6379
|
||||
master_link_status:up
|
||||
...
|
||||
🔹[Redis] redis-2
|
||||
# Replication
|
||||
role:slave
|
||||
master_host:redis-0.redis
|
||||
master_port:6379
|
||||
master_link_status:up
|
||||
...
|
||||
🔹[RedisSentinel] redis-sentinel-0
|
||||
# Sentinel
|
||||
sentinel_masters:1
|
||||
...
|
||||
master0:name=mymaster,status=ok,address=redis-0.redis:6379,slaves=2,sentinels=3
|
||||
🔹[RedisSentinel] redis-sentinel-1
|
||||
# Sentinel
|
||||
sentinel_masters:1
|
||||
...
|
||||
master0:name=mymaster,status=ok,address=redis-0.redis:6379,slaves=2,sentinels=3
|
||||
🔹[RedisSentinel] redis-sentinel-2
|
||||
# Sentinel
|
||||
sentinel_masters:1
|
||||
...
|
||||
master0:name=mymaster,status=ok,address=redis-0.redis:6379,slaves=2,sentinels=3
|
||||
```
|
||||
***
|
||||
|
||||
## Version
|
||||
|
||||
Command:
|
||||
```bash
|
||||
sudo kube.sh --redis version
|
||||
```
|
||||
|
||||
Example of log:
|
||||
```bash
|
||||
🔹[Redis] Version
|
||||
✅[Redis] redis-0 | 7.4.2
|
||||
✅[Redis] redis-1 | 7.4.2
|
||||
✅[Redis] redis-2 | 7.4.2
|
||||
✅[RedisSentinel] redis-sentinel-0 | 7.4.2
|
||||
✅[RedisSentinel] redis-sentinel-1 | 7.4.2
|
||||
✅[RedisSentinel] redis-sentinel-2 | 7.4.2
|
||||
```
|
||||
***
|
||||
|
||||
## User list
|
||||
|
||||
Command:
|
||||
```bash
|
||||
sudo kube.sh --redis user
|
||||
```
|
||||
|
||||
Example of log:
|
||||
```bash
|
||||
🔹[Redis] User list
|
||||
default
|
||||
us1_example_com
|
||||
us2_example_com
|
||||
us3_example_com
|
||||
```
|
||||
@@ -0,0 +1,121 @@
|
||||
[KUBE](../../README.md) / [k3s](../k3s.md) / Worker
|
||||
|
||||
# Resource Transfer
|
||||
|
||||
- [Install](#install)
|
||||
- [Remove](#remove)
|
||||
- [Transfer site](#transfer-site)
|
||||
- [Pause for Agent to receive new tasks from the API](#pause-for-agent-to-receive-new-tasks-from-the-api)
|
||||
- [Removing the pause for Agent to receive new tasks from the API](#removing-the-pause-for-agent-to-receive-new-tasks-from-the-api)
|
||||
- [Tasks list](#tasks-list)
|
||||
- [Update ENV](#update-env)
|
||||
***
|
||||
|
||||
## Install
|
||||
|
||||
Command:
|
||||
```bash
|
||||
sudo kube.sh --worker install
|
||||
```
|
||||
|
||||
Example of log:
|
||||
```bash
|
||||
🔹[Worker] Install
|
||||
🔹[Worker] Preparing /app/kube/assets/yaml/worker.yaml
|
||||
🔹[K3S] Applying YAML /app/kube/data/yaml/worker.yaml
|
||||
💡[K3S] Waiting for pods to be ready... | 1 not ready
|
||||
💡[K3S] Waiting for pods to be ready... | 1 not ready
|
||||
```
|
||||
***
|
||||
|
||||
## Remove
|
||||
|
||||
Command:
|
||||
```bash
|
||||
sudo kube.sh --Worker remove
|
||||
```
|
||||
***
|
||||
|
||||
## Execute task
|
||||
|
||||
Command:
|
||||
```bash
|
||||
sudo kube.sh --worker task <file> [domain]
|
||||
```
|
||||
|
||||
Example of log:
|
||||
```bash
|
||||
🔹[Worker] Task: /_data/worker/tasks/6d5b3169-a15f-4007-8cc7-ebfc8d75e3b2.task
|
||||
🔹[Worker] Action: test
|
||||
🔹[Worker] Database URL: https://wp.krumax.cz/transfer_36b91e68-53d3-49ac-922a-0031e664125b/0bf26901-c12d-4015-9bbe-cefc5c1a92d6.sql.zip
|
||||
🔹[Worker] Files URL: https://wp.krumax.cz/transfer_36b91e68-53d3-49ac-922a-0031e664125b/0bf26901-c12d-4015-9bbe-cefc5c1a92d6.zip
|
||||
🔹[Worker] Download archive database --> /app/transfers/us00.krumax.cz/us00.krumax.cz.sql.zip
|
||||
🔹[Worker] Download archive files --> /app/transfers/us00.krumax.cz/us00.krumax.cz.zip
|
||||
🔹[Worker] Create site: us00.krumax.cz
|
||||
🔹Files source: /app/transfers/us00.krumax.cz/us00.krumax.cz.zip
|
||||
🔹Database source: /app/transfers/us00.krumax.cz/us00.krumax.cz.sql.zip
|
||||
🔹[OpenLiteSpeed] Pod: openlitespeed-0 | Restart...
|
||||
🔹[OpenLiteSpeed] Pod: openlitespeed-1 | Restart...
|
||||
✅[Worker] Action: test | Success
|
||||
```
|
||||
***
|
||||
|
||||
## Tasks list
|
||||
|
||||
Command:
|
||||
```bash
|
||||
sudo kube.sh --worker list
|
||||
```
|
||||
|
||||
Example of log:
|
||||
```bash
|
||||
🔹[Worker] Task list
|
||||
# | Task | Action | Status | Time, sec
|
||||
---------------------------------------------------------------------------
|
||||
1 | d580040f-b3b8-43e1-af7a-8e35c80a688c | test | new | ?
|
||||
2 | pause | pause | execution | 691175
|
||||
```
|
||||
***
|
||||
|
||||
## Pause for Agent to receive new tasks from the API (pause)
|
||||
|
||||
Command:
|
||||
```bash
|
||||
sudo kube.sh --worker down
|
||||
```
|
||||
|
||||
Example of log:
|
||||
```bash
|
||||
🔹[Worker] Put on pause...
|
||||
```
|
||||
***
|
||||
|
||||
## Removing the pause for Agent to receive new tasks from the API (unpause)
|
||||
|
||||
Command:
|
||||
```bash
|
||||
sudo kube.sh --worker up
|
||||
```
|
||||
|
||||
Example of log:
|
||||
```bash
|
||||
🔹[Worker] Resuming from pause...
|
||||
```
|
||||
***
|
||||
|
||||
## Reload
|
||||
|
||||
Command:
|
||||
```bash
|
||||
sudo kube.sh --worker reload
|
||||
```
|
||||
|
||||
Example of log:
|
||||
```bash
|
||||
🔹[Worker] Reload...
|
||||
🔹[Worker] Updated ENV:
|
||||
API_URL: http://api.sodew.ai/api/tasks
|
||||
WORKER_ID: worker-dev
|
||||
GETTING_PAUSE: 30
|
||||
SENDING_PAUSE: 15
|
||||
```
|
||||
@@ -0,0 +1,73 @@
|
||||
[KUBE](../README.md) / Restore
|
||||
|
||||
# Restore
|
||||
|
||||
The restore process is divided into three stages:
|
||||
1. Restoring website files from the `<domain>` directory or the `<domain>.tar.gz` archive.
|
||||
2. Restoring the `<domain>.conf` file.
|
||||
3. Restoring the database from the `<domain>.sql` file or the `<domain>.sql.tar.gz` archive.
|
||||
|
||||
> [!WARNING]
|
||||
> If an error occurs at any stage, the process does not stop.
|
||||
|
||||
> [!WARNING]
|
||||
> Files, databases, and other resources at each stage are either pre-cleaned or immediately overwritten without confirmation.
|
||||
|
||||
|
||||
## Commands
|
||||
|
||||
### `-r, --restore <domain> [action]`
|
||||
Restore site files and database from backup for a `domain`.
|
||||
|
||||
Example:
|
||||
```bash
|
||||
sudo kube.sh -r example.com
|
||||
```
|
||||
|
||||
The source of resources for recovery is the directories defined in `backupPath` and `backupLongTermPath`.\
|
||||
In the backup folder is searched for 3 types of resources:
|
||||
- `<source path>/<date>/<marker>/<domain>` - directory with site files (`file:d`)
|
||||
- `<source path>/<date>/<marker>/<domain>.tar.gz` - site file archive (`file:a`)
|
||||
- `<source path>/<date>/<marker>/<domain>.sql` - site database SQL-file (`db:f`)
|
||||
- `<source path>/<date>/<marker>/<domain>.sql.tar.gz` - site database archive (`db:a`)
|
||||
- `<source path>/<date>/<marker>/<domain>.conf` - site database archive (`conf`)
|
||||
|
||||
The search results in a list of format: `<counter>: <data> <marker> [<list of resource>]`. Then you should specify the number of the selected marker for restore.
|
||||
|
||||
> [!NOTE]
|
||||
> If one resource is selected (`file:d`/`file:a`/`db:f`/`db:a`/`conf`), only one resource will be restored. The other will remain unchanged.
|
||||
|
||||
> [!NOTE]
|
||||
> If there's a `file:d` and a `file:a`. Priority is given to `file:d`. If there's a `db:f` and a `db:a`. Priority is given to `db:f`.
|
||||
|
||||
> [!NOTE]
|
||||
> Once database are restored, the Redis keys for the domain are deleted.
|
||||
|
||||
Example:
|
||||
```bash
|
||||
1: 2025-04-29 14-22-22 [file:d file:a db:f conf]
|
||||
2: 2025-04-29 14-20-20 [file:d db:a]
|
||||
3: 2025-04-29 12-00-00 [file:a conf]
|
||||
4: 2025-04-29 _first [db:a]
|
||||
```
|
||||
|
||||
You can specify an additional parameter after the domain:
|
||||
- `list` - will display a list of available markers for restore
|
||||
- `last` - automatic site restore from the `last backup`
|
||||
- `full` - automatic site restore from the last `FULL backup`
|
||||
- `auto` - automatic site restore from the last `FULL backup` or the `last backup`
|
||||
- `N` - automatic site restore from the `last backup #N` (N: 1+)
|
||||
|
||||
`FULL backup` is a backup that contains a copy of the site files, a copy of the database, and a copy of the .conf file\
|
||||
`last backup #N` marker number (starting from 1) in the list sorted by creation time (can be seen with the list command)
|
||||
|
||||
Example:
|
||||
```bash
|
||||
sudo kube.sh -r example.com list
|
||||
sudo kube.sh -r example.com last
|
||||
sudo kube.sh -r example.com auto
|
||||
sudo kube.sh -r example.com 3
|
||||
```
|
||||
|
||||
> [!WARNING]
|
||||
> Restoring from the last full copy will be done without question.
|
||||
@@ -0,0 +1,24 @@
|
||||
[KUBE](../README.md) / Script
|
||||
|
||||
# Script
|
||||
|
||||
> A set of scripts to execute.
|
||||
|
||||
## Commands
|
||||
|
||||
### `--script <script>`
|
||||
|
||||
Script:
|
||||
- `backup` - Creating a backup (within a day) of all sites and then synchronizing the backups (within a day) with external storage.
|
||||
- `backup-clean` - Cleanup of old backups on the current host and on external storage.
|
||||
- `backup-long-term` - Create/update a long-term backup.
|
||||
- `report-backup-last` - Report on creating the last backup.
|
||||
- `report-backup-day` - Backup report for the current day.
|
||||
- `report-status` - Creating and sending a report on the status of k3s and its nodes
|
||||
- `mariadb-dump` - Creating a full backup (of all databases) of MariaDB
|
||||
- `worker-observer` - Launching the task observer
|
||||
|
||||
Example:
|
||||
```bash
|
||||
sudo kube.sh --script backup
|
||||
```
|
||||
@@ -0,0 +1,36 @@
|
||||
[KUBE](../README.md) / Shell
|
||||
|
||||
# Shell
|
||||
|
||||
> Opening the shell in the pods.
|
||||
|
||||
## Commands
|
||||
|
||||
### `--shell [cli]`
|
||||
|
||||
> [!NOTE]
|
||||
> Specifying `cli` will open the appropriate CLI where possible (`MariaDB`, `Redis`, `Redis Sentinel`)
|
||||
|
||||
Example:
|
||||
```bash
|
||||
sudo kube.sh --shell
|
||||
sudo kube.sh --shell cli
|
||||
```
|
||||
|
||||
Examples of responses:
|
||||
```bash
|
||||
🔹Shell
|
||||
1: mariadb-master-0 [Running]
|
||||
2: mariadb-slave-0 [Running]
|
||||
3: openlitespeed-0 [Running]
|
||||
4: openlitespeed-1 [Running]
|
||||
5: postfix-78c47b95f6-42jcq [Running]
|
||||
6: redis-0 [Running]
|
||||
7: redis-1 [Running]
|
||||
8: redis-2 [Running]
|
||||
9: redis-sentinel-0 [Running]
|
||||
10: redis-sentinel-1 [Running]
|
||||
11: redis-sentinel-2 [Running]
|
||||
12: worker-6cd4bdb6b8-c6f5d [Running]
|
||||
Specify the pod number [0]:
|
||||
```
|
||||
@@ -0,0 +1,191 @@
|
||||
[KUBE](../README.md) / Site
|
||||
|
||||
# Site
|
||||
|
||||
## Site Creation
|
||||
|
||||
Stages of Site Creation:
|
||||
|
||||
### 1. Configuration.
|
||||
|
||||
The configuration, as a file (`<dataPath>/config/<domain>.config`), contains the connection parameters for `MariaDB` and `Redis`. The configuration can be prepared before starting the site creation or will be generated automatically.
|
||||
|
||||
Example configuration file:
|
||||
```
|
||||
databaseName=example_com
|
||||
databaseUser=example_com
|
||||
redisUser=example_com
|
||||
databasePass=qwerty
|
||||
redisPass=qwerty
|
||||
```
|
||||
|
||||
Fields not specified will be generated automatically. The names of the database, database user, and `Redis` user are generated based on the domain using the functions `mariadbDomain2id` and `domain2redis`.
|
||||
|
||||
### 2. Initial Check.
|
||||
|
||||
Before starting the site creation, some configuration checks are performed:
|
||||
* Check for absence of the vhost directory for the domain (`/path/to/vhosts/example.com`)
|
||||
* Check for absence of the domain entry in the `OpenLiteSpeed` configuration
|
||||
* Check for absence of the specified database
|
||||
* Check for absence of the specified database user
|
||||
* Check for absence of the specified `Redis` user
|
||||
|
||||
### 3. Distribution Check.
|
||||
|
||||
When creating a site, you can specify the source for the site files as `pathF` and the source for the database as `pathD`. `pathF` can be a directory or an archive file. `pathD` can be a SQL file for import as is, or an archive file.
|
||||
|
||||
If a file source `pathF` is specified, its presence is checked. Otherwise, the default distribution is used:
|
||||
* for `Wordpress`: the directory `<assetsPath>/vhost.wordpress` (if the directory is missing, the file `<assetsPath>/vhost.wordpress.tar.gz` is used)
|
||||
* for `non-Wordpress`: the directory `<assetsPath>/vhost.default` (if the directory is missing, the file `<assetsPath>/vhost.default.tar.gz` is used)
|
||||
|
||||
If the specified data sources are not found, or the default resources are not found, the process is aborted.
|
||||
|
||||
### 4. Site Creation.
|
||||
|
||||
When a site is created, the following steps occur:
|
||||
* creation of the site directory structure `<vhostPath>/<domain>/{www,tmp,session}`
|
||||
* copying site files from the source to the site directory
|
||||
* creation of an OS user for the site files and changing access rights
|
||||
* creation of a record in the `OpenLiteSpeed` configuration
|
||||
* creation of a database and database user in `MariaDB`
|
||||
* creation of a `Redis` user
|
||||
* importing the database from the source, if specified
|
||||
* writing database connection parameters (for `Wordpress`)
|
||||
* writing Redis connection parameters (for `Wordpress`)
|
||||
* writing to hosts (?!)
|
||||
* restarting `OpenLiteSpeed`
|
||||
|
||||
***
|
||||
|
||||
## Site on Wordpress creation
|
||||
|
||||
* MariaDB
|
||||
> The database name and database user name are formed on the basis of domain conversion, where all `.-` are replaced by `_`. If necessary, the conversion rule can be changed (mariadbDomain2id function). When generating connection parameters, the database password is saved to the `data/<domain>.mariadb` file.
|
||||
|
||||
Example for `example.com`:
|
||||
```php
|
||||
define( 'DB_HOST', 'mariadb-master' );
|
||||
define( 'DB_NAME', 'example_com' );
|
||||
define( 'DB_USER', 'example_com' );
|
||||
define( 'DB_PASSWORD', 'qwerty' );
|
||||
```
|
||||
|
||||
* Redis
|
||||
> Redis username is generated based on domain conversion, where all `.-` are replaced by `_`. The conversion rule can be changed if necessary (`domain2redis` function). When generating connection parameters, the database password is stored in the `data/<domain>.redis` file.
|
||||
|
||||
Example for `example.com`:
|
||||
```php
|
||||
define( 'WP_REDIS_HOST', 'redis-0.redis' );
|
||||
define( 'WP_REDIS_PORT', '6379' );
|
||||
define( 'WP_REDIS_PASSWORD', ['example_com', 'qwerty'] );
|
||||
define( 'WP_REDIS_PREFIX', 'example_com:' );
|
||||
```
|
||||
|
||||
> [!NOTE]
|
||||
> A separate Redis user is created for each Wordpress and a PrefixKey is also specified to separate keys in Redis.
|
||||
***
|
||||
|
||||
## Commands
|
||||
|
||||
### `--site add <domain> [pathF] [pathD]`
|
||||
Adding a site
|
||||
|
||||
Example:
|
||||
```bash
|
||||
sudo kube.sh --site add example.com
|
||||
sudo kube.sh --site add example.com /path/to/files /path/to/database
|
||||
```
|
||||
***
|
||||
|
||||
### `--site wp <option>`
|
||||
Add site(s) on Wordpress. Option:
|
||||
- `list` - add list of domains with Wordpress from a default file: (`domainsList` in `config.sh`)
|
||||
- `<file>` - add list of domains with Wordpress from a file (e.g., `/path/to/file.txt`)
|
||||
- `<domain>` [pathF] [pathD] - add a domain with Wordpress (e.g., `example.com`)
|
||||
|
||||
Example:
|
||||
```bash
|
||||
sudo kube.sh --site wp /path/to/file.txt
|
||||
sudo kube.sh --site wp list
|
||||
sudo kube.sh --site wp example.com
|
||||
sudo kube.sh --site wp example.com /path/to/files /path/to/database
|
||||
```
|
||||
***
|
||||
|
||||
### `--site remove <domain>`
|
||||
|
||||
> [!WARNING]
|
||||
> Site remove (site directories, site database, `OpenLiteSpeed` configuration entries).
|
||||
|
||||
Example:
|
||||
```bash
|
||||
sudo kube.sh --remove example.com
|
||||
```
|
||||
***
|
||||
|
||||
### `--site status [domain]`
|
||||
|
||||
When specifying a domain, the following checks are performed:
|
||||
* Presence of the domain in the `OpenLiteSpeed` configuration
|
||||
* Presence of the domain in the list of stopped sites (OpenLiteSpeed)
|
||||
* Presence of the domain directory in the virtual hosts directory (`vhostsPath`)
|
||||
* Presence of the `WordPress` configuration file (`wp-config.php`)
|
||||
* Checking the database name entry in the WordPress configuration and verifying its existence
|
||||
* Checking the database user entry in the WordPress configuration and verifying its existence
|
||||
* Checking database connectivity (retrieving the list of tables in the database)
|
||||
* Checking the Redis user entry in the `WordPress` configuration and verifying its existence
|
||||
* Checking connectivity to `Redis` (using the `PING` command)
|
||||
* Checking the site's HTTP response
|
||||
|
||||
If the domain is not specified, the following checks are performed for all domains:
|
||||
* Presence of the domain in the list of stopped sites (`OpenLiteSpeed`)
|
||||
* Presence of the domain directory in the virtual hosts directory (`vhostsPath`)
|
||||
* Presence of the `WordPress` configuration file (`wp-config.php`)
|
||||
* Checking the database name entry in the `WordPress` configuration and verifying its existence
|
||||
* Checking the database user entry in the `WordPress` configuration and verifying its existence
|
||||
* Checking the `Redis` user entry in the `WordPress` configuration and verifying its existence
|
||||
|
||||
Example:
|
||||
```bash
|
||||
sudo kube.sh --site
|
||||
sudo kube.sh --site example.com
|
||||
```
|
||||
|
||||
Examples of responses:
|
||||
```bash
|
||||
🔹Site | example.com
|
||||
✅example.com | Found in OpenLiteSpeed configuration
|
||||
✅example.com | Directory: /_data/vhosts/example.com
|
||||
✅example.com | Wordpress config: /_data/vhosts/example.com/www/wp-config.php
|
||||
✅example.com | MariaDB database: example_com
|
||||
✅example.com | MariaDB user: example_com
|
||||
✅example.com | MariaDB tables: 10
|
||||
✅example.com | Redis user: example_com
|
||||
✅example.com | Redis ping: PONG
|
||||
✅example.com | Site response: 200
|
||||
```
|
||||
|
||||
```bash
|
||||
🔹Site | all
|
||||
## | Domain | CFG | DIR | OLS | MD | MU | RU | WP
|
||||
--------------------------------------------------------------------------------
|
||||
1 | example1.com | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅
|
||||
2 | example2.com | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅
|
||||
3 | example3.com | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅
|
||||
4 | example4.com | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅
|
||||
5 | example5.com | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅
|
||||
6 | example6.com | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅
|
||||
7 | example7.com | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | --
|
||||
8 | example8.com | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | --
|
||||
9 | Example | --- | --- | ✅ | -- | -- | -- | --
|
||||
```
|
||||
|
||||
Where:
|
||||
- `CFG` - existence of the configuration file `$dataPath/config/<domain>.config`
|
||||
- `DIR` - existence of the directory `$vhostsPath/<domain>`
|
||||
- `OLS` - existence of an entry in the `OpenLiteSpeed` configuration
|
||||
- `MD` - existence of the database (based on the entry in the configuration file)
|
||||
- `MU` - existence of the database user (based on the entry in the configuration file)
|
||||
- `RU` - existence of the Redis user (based on the entry in the configuration file)
|
||||
- `WP` - existence of the WP configuration file `$vhostsPath/<domain>/www/wp-config.php`
|
||||
)
|
||||
@@ -0,0 +1,23 @@
|
||||
[KUBE](../README.md) / Storage
|
||||
|
||||
# Storage
|
||||
|
||||
## Commands
|
||||
|
||||
### `-s, --storage [option]`
|
||||
Copying backups to external storage. Options:
|
||||
- `rsync` - The backup directory `<backup path>/<current date>` is synchronized to the specified address `rsyncUri` using `rSync`.
|
||||
- `ssh` - The backup directory `<backup path>/<current date>` is synchronized to the specified address `sshHost` using `rSync`.
|
||||
|
||||
> [!NOTE]
|
||||
> The default value (`rsync` or `ssh`) is set by the `storageType` variable in the configuration file `config.sh`.
|
||||
|
||||
> [!NOTE]
|
||||
> For correct operation it is necessary to set up SSH-keys for authentication on the external storage. Create a directory (specified in `sshPath`) and grant necessary user rights on the external storage.
|
||||
|
||||
Example:
|
||||
```bash
|
||||
sudo kube.sh -s
|
||||
sudo kube.sh -s rsync
|
||||
sudo kube.sh -s ssh
|
||||
```
|
||||
@@ -0,0 +1,24 @@
|
||||
[KUBE](../README.md) / Test
|
||||
|
||||
# Test
|
||||
|
||||
> [!NOTE]
|
||||
> Testing the operation of individual units or the entire system.
|
||||
|
||||
## Commands
|
||||
|
||||
### `--test <option>`
|
||||
Options:
|
||||
- `mariadb` - A database with a random name is created on the master device and the existence of the created database is checked on the slave device.
|
||||
- `redis` - A key with a random name is created on the master and the existence of the created key is verified on the replicas.
|
||||
- `site` - A site is created (without `WordPress`). MariaDB (a database and user are created). `Redis` (a user is created). The site is opened via HTTP (the response code is checked). The site is deleted.
|
||||
- `wordpress` - A WordPress site is created. `MariaDB` (a database and user are created). `Redis` (a user is created). The site is opened via HTTP (the response code is checked). The site is deleted.
|
||||
- `mailint` - Internal test of sending a letter from one user to another.
|
||||
- `mailext` - Test sending a letter to the specified address (In progress...)
|
||||
|
||||
Example:
|
||||
```bash
|
||||
sudo kube.sh --test mariadb
|
||||
sudo kube.sh --test redis
|
||||
sudo kube.sh --test mailint
|
||||
```
|
||||
@@ -0,0 +1,214 @@
|
||||
[KUBE](../README.md) / Transfer sites
|
||||
|
||||
# Transfer sites
|
||||
|
||||
> [!NOTE]
|
||||
> In progress...
|
||||
|
||||
- [Transfer via console](#transfer-via-console)
|
||||
- [Transfer via plugin Wordpress](#transfer-via-plugin-worpress)
|
||||
- [Workflow 1. Cloning a website via the WordPress plugin](#workflow-1-cloning-a-website-via-the-wordpress-plugin)
|
||||
- [Workflow 2. Cloning websites to SODEW servers via the WordPress plugin](#workflow-2-cloning-websites-to-sodew-servers-via-the-wordpress-plugin)
|
||||
- [Workflow 3. Detailed description of the process](#workflow-3-detailed-description-of-the-process)
|
||||
|
||||
## Transfer via console:
|
||||
|
||||
```bash
|
||||
sudo kube.sh --worker task </path/to/configFile> [domain]
|
||||
```
|
||||
|
||||
### Configuration analysis.
|
||||
|
||||
Example:
|
||||
|
||||
```ini
|
||||
action=test
|
||||
files_url=https://wp.krumax.cz/transfer_36b91e68-53d3-49ac-922a-0031e664125b/2b3d170e-9f50-435c-b189-b8c3a45cbb8a.zip
|
||||
database_url=https://wp.krumax.cz/transfer_36b91e68-53d3-49ac-922a-0031e664125b/2b3d170e-9f50-435c-b189-b8c3a45cbb8a.sql.zip
|
||||
domain=new.domain.com
|
||||
status=new
|
||||
```
|
||||
|
||||
Where:
|
||||
|
||||
* `action` — the main operation (`copy`/`test`/`migrate`/...)
|
||||
* `files_url` — link to the files archive
|
||||
* `database_url` — link to the DB archive
|
||||
* `status` — execution status:
|
||||
* `new` - new task
|
||||
* `execution` - in progress
|
||||
* `success` - task completed successfully
|
||||
* `failed` - task failed
|
||||
* `domain` - new domain (optional field)
|
||||
|
||||
> [!NOTE]
|
||||
> Working only action `test` (18.11.2025).
|
||||
|
||||
> [!NOTE]
|
||||
> If a domain is specified in the command call, the domain from the configuration file is ignored.
|
||||
|
||||
> [!NOTE]
|
||||
> If the domain is not specified in the command and not specified in the configuration file, it will be assigned automatically from the available ones (`domainsList`). If none are available, the task fails.
|
||||
|
||||
### Work
|
||||
|
||||
**Stage 1**. Configuration analysis.
|
||||
|
||||
**Stage 2**. Availability check and archive download.
|
||||
|
||||
The download is performed into the folder `<transferPath>/<domain>/`:
|
||||
|
||||
* `<transferPath>/<domain>/<domain>.zip` — files archive
|
||||
* `<transferPath>/<domain>/<domain>.sql.zip` — DB archive
|
||||
|
||||
**Stage 3**. Depending on the task:
|
||||
|
||||
* `test` - A site is created based on the downloaded backup.
|
||||
* `copy` - in progress...
|
||||
* `migrate` - in progress...
|
||||
|
||||
**Stage 4**. The status is changed in the configuration file
|
||||
|
||||
* `success` - upon successful completion of the task
|
||||
* `failed` - upon errors at any stage
|
||||
|
||||
## Transfer via plugin Wordpress
|
||||
|
||||
When using the plugin "SODEW Backup & Transfer" ([https://gitlab.wedos.org/mk250/transfer-plugin](https://gitlab.wedos.org/mk250/transfer-plugin)), it is possible to copy a site to SODEW hosting.
|
||||
|
||||
### Preparation
|
||||
|
||||
**Stage 1**. Create a full site backup in the plugin.
|
||||
|
||||
**Stage 2**. Create a task "Launch a copy of the website on SODEW hosting".
|
||||
|
||||
### Work
|
||||
|
||||
**Stage 1**. Sending a request to create a copy of the site for testing to `api.sodew.ai`. Request parameters:
|
||||
|
||||
* `action` – selected action
|
||||
* `transfer_id` – plugin identifier
|
||||
* `backup_id` – backup identifier
|
||||
* `base_url` – site URL (WordPress)
|
||||
* `base_path` – base path
|
||||
|
||||
Example:
|
||||
|
||||
```json
|
||||
[
|
||||
"action":"test",
|
||||
"transfer_id":"22222222-53d3-49ac-922a-0031e664125b",
|
||||
"backup_id":"33333333-c976-43c2-bdee-d7d6ec21900a",
|
||||
"base_url":"https://wp.us1.com",
|
||||
"base_path":"/usr/www/wp.us1.com",
|
||||
]
|
||||
```
|
||||
|
||||
**Stage 2**. Processing the request on the `api.sodew.ai` side.
|
||||
|
||||
1. Parameter validation
|
||||
2. Preparation and validation of URLs to the backup:
|
||||
```ini
|
||||
<base_url>/transfer_<transfer_id>/<backup_id>.zip
|
||||
<base_url>/transfer_<transfer_id>/<backup_id>.sql.zip
|
||||
```
|
||||
3. Creating a task for Workers
|
||||
|
||||
**Stage 3**. Request from the Worker (agent) to `api.sodew.ai` to obtain a new task and receiving it.
|
||||
The task is assigned to the Worker.
|
||||
|
||||
**Stage 4**. Processing of the `api.sodew.ai` response by the Worker (agent) and creating a task for the `kube.sh` script.
|
||||
|
||||
A task file `<task_id>.task` is created in the `workerTasksPath` folder with the following content:
|
||||
|
||||
* `action` – action
|
||||
* `files_url` – URL to the files archive
|
||||
* `database_url` – URL to the database archive
|
||||
* `domain` – domain (optional)
|
||||
* `status` – new (task status: new)
|
||||
|
||||
**Stage 5**. Launching the `kube.sh` task handler via CRON, searching for new tasks and starting execution of the found new task.
|
||||
|
||||
**Stage 6**. Validation of the task parameters. Checking the availability of backup files. Downloading the backup files. Creating the site. (Detailed: [Transfer](#transfer))
|
||||
|
||||
**Stage 7**. Monitoring of the task execution status by the Worker (agent) and sending reports to `api.sodew.ai`.
|
||||
|
||||
**Stage 8**. Receiving task execution reports from the Worker (agent).
|
||||
|
||||
**Stage 9**. Updating the task execution status on `api.sodew.ai` by the plugin.
|
||||
|
||||
## Workflow 1. Cloning a website via the WordPress plugin.
|
||||
|
||||
```mermaid
|
||||
flowchart TB;
|
||||
|
||||
subgraph SW[Server-worker]
|
||||
WO(Worker-observer<br>CRON)
|
||||
WA(Worker-agent)
|
||||
TP[[workerTasksPath/task_id.task<br>action<br>files_url<br>database_url<br>status=new]]
|
||||
CS[Сopy of user's website]
|
||||
end
|
||||
subgraph API[api.sodew.ai]
|
||||
AT(task_id<br>files_url<br>database_url)
|
||||
end
|
||||
subgraph US[User site]
|
||||
WP(Plugin WP<br>action<br>transfer_id<br>backup_id<br>base_url)
|
||||
end
|
||||
|
||||
WP -->|1. create task<br>check status| AT
|
||||
WA -->|2. get new task<br>send statuses| AT
|
||||
WA -->|3. save new task| TP
|
||||
WO -->|4. executing tasks| TP
|
||||
WO -->|5. load files| US
|
||||
WO -->|6. create site| CS
|
||||
```
|
||||
|
||||
## Workflow 2. Cloning websites to SODEW servers via the WordPress plugin.
|
||||
|
||||
```mermaid
|
||||
flowchart LR;
|
||||
US[[User sites...]]
|
||||
SW[[Server-workers...]]
|
||||
API(api.sodew.ai)
|
||||
|
||||
US -->|tasks...| API -->|tasks...| SW
|
||||
```
|
||||
|
||||
## Workflow 3. Detailed description of the process.
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
|
||||
alt task
|
||||
Wordpress plugin ->> api.sodew.ai: new task
|
||||
|
||||
loop every 30sec
|
||||
Wordpress plugin ->> api.sodew.ai: how status task?
|
||||
activate api.sodew.ai
|
||||
api.sodew.ai ->> Wordpress plugin: status task is ...
|
||||
deactivate api.sodew.ai
|
||||
end
|
||||
end
|
||||
|
||||
loop every 30sec
|
||||
Worker-Agent ->> api.sodew.ai: receiving new tasks
|
||||
activate api.sodew.ai
|
||||
api.sodew.ai ->> Worker-Agent: <task>
|
||||
deactivate api.sodew.ai
|
||||
activate Worker-Agent
|
||||
Worker-Agent ->> workerTasksPath: saving a new task <task>
|
||||
deactivate Worker-Agent
|
||||
end
|
||||
|
||||
loop every 15sec
|
||||
Worker-Agent ->> workerTasksPath: reading task statuses
|
||||
activate Worker-Agent
|
||||
Worker-Agent ->> api.sodew.ai: sending task statuses
|
||||
deactivate Worker-Agent
|
||||
end
|
||||
|
||||
loop every 1min
|
||||
Worker-Observer ->> workerTasksPath: get new task
|
||||
Note over Worker-Observer: Execute task...
|
||||
end
|
||||
```
|
||||
Reference in New Issue
Block a user