ูƒูŠููŠุฉ ุฑูุน ุงู„ุฎุงุฏู… ุงู„ุฎุงุต ุจูƒ ุนู„ู‰ RaspberryPI ุงู„ู‚ุงุฆู… ุนู„ู‰ ุนุงู…ู„ ุงู„ู…ูŠู†ุงุก

ู‚ุตุฉ ูƒูŠู ู‚ู…ุช ุจุชูƒูˆูŠู† ุงู„ุฎุฏู…ุงุช ููŠ ุนุงู…ู„ ุงู„ู…ูŠู†ุงุก ุนู„ู‰ Raspberry PI ูˆู„ู…ุงุฐุง ู‚ุฏ ู„ุง ุชูƒูˆู† ู‡ุฐู‡ ุฃูุถู„ ููƒุฑุฉ.


ู…ู‚ุฏู…ุฉ (ุฃูˆ ูƒูŠู ุจุฏุฃ ูƒู„ ุดูŠุก)


ุจุฏุฃ ูƒู„ ุดูŠุก ู…ู†ุฐ ูˆู‚ุช ุทูˆูŠู„ู‚ุจู„ ุจุถุน ุณู†ูˆุงุช. ุญุฏุซ ุฐู„ูƒ ุญุชู‰ ุงู†ุชู‡ู‰ ุจูŠ ุงู„ุฃู…ุฑ ููŠ ุงู„ุตูŠู† ูˆุงุถุทุฑุฑุช ุฅู„ู‰ ุงู„ุงุชุตุงู„ ุจุทุฑูŠู‚ุฉ ุฃูˆ ุจุฃุฎุฑู‰ ุจุงู„ุนุงู„ู… ุงู„ุฎุงุฑุฌูŠ. ู„ู… ุฃูƒู† ุฃุซู‚ ุญู‚ู‹ุง ููŠ VPN ูˆุงู„ูˆูƒู„ุงุก ุงู„ุฎุงุฑุฌูŠูŠู† ุŒ ู„ุฐู„ูƒ ู‚ุฑุฑุช ุฑูุน DigitalOcean ู…ุน ุงู„ูˆูƒูŠู„ ุงู„ุฎุงุต ุจูŠ. ุญุฏุซ ุฐู„ูƒ ุชู…ุงู…ู‹ุง ุฃู†ู‡ ุจู…ุฑูˆุฑ ุงู„ูˆู‚ุช ุŒ ู†ู…ุง ุงู„ุฎุงุฏู… ู…ุน ูˆูƒูŠู„ ู…ุน ุงุฎุชู„ุงูุงุช ู…ุฎุชู„ูุฉ: ู…ู† ุชุฎุฒูŠู† ุงู„ู…ู„ูุงุช ( Syncthing) ุฅู„ู‰ CI ( Jenkins).


ุนู†ุฏ ุงู„ุนูˆุฏุฉ ุฅู„ู‰ ุฑูˆุณูŠุง ุŒ ุชู‚ุฑุฑ ุชุฑูƒ DO ู„ุจุนุถ ุฃู†ูˆุงุน ุงู„ุงุณุชุถุงูุฉ ุงู„ุฐุงุชูŠุฉ. ู„ู… ุฃุฑุบุจ ููŠ ุดุฑุงุก ุฎุงุฏู… ู…ู†ูุตู„ ู„ู‡ุฐุง - ุฅู†ู‡ ู…ูƒู„ู ุŒ ูˆุญุชู‰ ุงู„ุขู† ู„ูŠุณุช ู‡ู†ุงูƒ ุญุงุฌุฉ ุŒ ูˆู„ู‡ุฐุง ุงู„ุณุจุจ ุฃุฎุฐุช Raspberry PI 4B. ุจุทุจูŠุนุฉ ุงู„ุญุงู„ ุŒ ุงุถุทุฑุฑุช ุฅู„ู‰ ู†ู‚ู„ ุฌู…ูŠุน ุงู„ุฎุฏู…ุงุช ุงู„ุฃุณุงุณูŠุฉ ู…ู† DO ุฅู„ู‰ ู‡ุฐุง ุงู„ุฌู‡ุงุฒ ุŒ ูˆุงู„ุฐูŠ ุณูŠูƒูˆู† ู…ูˆุถูˆุน ู‡ุฐุง ุงู„ู…ู†ุดูˆุฑ.


ุชู…ู‡ูŠุฏูŠ


ูƒุงู† ู…ู† ุงู„ุถุฑูˆุฑูŠ ุชูƒูˆูŠู† ุงู„ุฎุฏู…ุงุช ุงู„ุชุงู„ูŠุฉ:


  • Syncthing - ุชุฒุงู…ู† ุงู„ู…ู„ู
  • ุฌู†ูƒูŠู†ุฒ - CI
  • ุชู„ุบุฑุงู -
  • Influxdb - ุฑุณูˆู…ุงุช ูˆุญุฏุฉ ุงู„ู…ุนุงู„ุฌุฉ ุงู„ู…ุฑูƒุฒูŠุฉ ูˆูˆุญุฏุฉ ู…ุนุงู„ุฌุฉ ุงู„ุฑุณูˆู…ุงุช ูˆุบูŠุฑู‡ุง
  • ุฌุฑุงูุงู†ุง - |
  • ูŠุฃุฌูˆุฌ - ุจูˆุงุจุฉ
  • Radicale - ู…ุฒุงู…ู†ุฉ ุงู„ุชู‚ุงูˆูŠู… / ุฌู‡ุงุช ุงู„ุงุชุตุงู„

ุฅู„ู‰ ุฌุงู†ุจ:


  • ูƒุงู† ู…ู† ุงู„ู…ูุชุฑุถ ุชุฎุฒูŠู† ุงู„ู…ู„ูุงุช ูˆุงู„ุจูŠุงู†ุงุช ุนู„ู‰ ุฒูˆุฌ ู…ู† ู…ุญุฑูƒุงุช ุงู„ุฃู‚ุฑุงุต ุงู„ู…ุญู…ูˆู„ุฉ USB3ููŠ ุดูƒู„ ู…ุดูุฑ ( LUKS)
  • ุชู… ุฅุฎูุงุก ุฌู…ูŠุน ูˆุงุฌู‡ุงุช ุงู„ูˆูŠุจ ุฎู„ู ูˆูƒูŠู„ Nginx ุงู„ุนูƒุณูŠ

ุงู„ู…ุดุงูƒู„ ูˆุงู„ูุฑูˆู‚ ุงู„ุฏู‚ูŠู‚ุฉ


ุฃูˆุฏ ุนู„ู‰ ุงู„ููˆุฑ ุฃู† ุฃุชุญุฏุซ ุนู† ุงู„ู…ุดุงูƒู„ ุงู„ุชูŠ ู†ุดุฃุช ุฃุซู†ุงุก ุชุฌู…ูŠุน ู‡ุฐุง ุงู„ุฃู…ุฑ ุจุฃูƒู…ู„ู‡ ูˆ / ุฃูˆ ุงู„ุชูŠ ุชุธู‡ุฑ ุงู„ุขู†:


  • Raspberry PI 1A, . , , โ€”
  • RaspberryPI 4B ( ) USB . โ€” / . USB3
  • , . ( ) ( " ")
  • โ€” syncthing, , /
  • 60

โ€” 502 ssh.



, Micro SD 16GB ( ) Raspbian. .


  • Noobs
  • Micro SD Fat32
  • ( uNetbootin)
  • Raspberry PI

. : GUI . GUI, ssh GUI .


()


Elementary OS GUI (GParted disks) . , :


, .


โ€” ext4 LUKS.


  • GParted
    • Device -> Create partition table...
    • gpt
    • Apply
    • ext4
  • gnome-disks ( sudo apt install gnome-disk-utility) ( Disks):
    • ()
    • Format partition...
    • Ext 4
    • Password protect volume
    • Next
    • :
      • - UUID,
      • - Device,

. , RaspberryPI . :


: /dev/sdb1 โ€” , Device


dd if=/dev/urandom bs=4M count=1 of=/tmp/usb_decrypt_file
sudo cryptsetup luksAddKey /dev/sdb1 /tmp/usb_decrypt_file

.


: .


, . ()- /


Raspberry PI


, :


  • (sudo apt update && sudo apt -y dist-upgrade)
  • :
    • docker docker-compose (sudo apt -y install docker docker-compose)
    • Nginx(sudo apt -y install nginx). reverse-proxy

    • - (, /root/cryptfiles; )


    • /etc/crypttab :


      usb1_crypt UUID=___UUID /root/cryptfiles/_- luks

    • /etc/fstab


      /dev/mapper/usb1_crypt /media/pi/usb1 ext4 defaults,nofail 0 2

      :


      • /dev/mapper/usb1_crypt โ€” /dev/mapper/ + ( ) /etc/crypttab
      • /media/pi/usb1 โ€” . (mkdir /media/pi/usb1). โ€” , /mnt /media/$USER

    • ,




Nginx


bash, reverse-proxy .


:


  • , ,
  • , letsencrypt

reverse-proxy nginx

, โ€” mydomain.com. nginx /etc/nginx, /etc/nginx/autocompile.


compile_apps_configs.sh
#!/bin/bash

# Use "-pl" key in subname to make it like https://hostname/subname.
# E.g.: for https://my.domain/example will be used "-pl example"

APPS=("syncthing" "grafana" "radicale" "git" "jenkins")
APPS_PROXIES=(http://localhost:8880 http://localhost:3000 http://localhost:8882 http://localhost:8883 http://localhost:8884)
HOSTNAMES=(my.domain)
# HOSTNAMES=()

conf_file="/etc/nginx/sites-available/autocompiled.conf"
ln_file="/etc/nginx/sites-enabled/autocompiled.conf"

echo "" > "$conf_file"

for app_index in ${!APPS[*]}
do
    app="${APPS[app_index]}"
    app_proxy="${APPS_PROXIES[app_index]}"

    for host in ${HOSTNAMES[*]}
    do
        echo "`./compile_config.sh "$host" "$app_proxy" $app`" >> "$conf_file"
        echo "" >> "$conf_file"
    done
done

ln -s "$conf_file" "$ln_file"

compile_config.sh
#!/bin/bash

# FIRST ARG IS DOMAIN BASE

DOMAIN_BASE="$1"
shift

# THIRD ARG IS PROXY_PASS

PROXY_PATH=$(echo "$1" | sed -e "s/\//\\\\\//g")
PROXY_LOCATION=""
shift

HOSTNAME="$DOMAIN_BASE"

while [ -n "$1" ]
do
    case "$1" in
        "-pl") shift; PROXY_LOCATION="$(echo "$1" | sed -e "s/\//\\\\\//g")" ;;
        *) HOSTNAME="$1.$HOSTNAME" ;;
    esac

    shift
done

cat template.conf | sed "s/HOSTNAME_BASE/$DOMAIN_BASE/g" | sed "s/HOSTNAME/$HOSTNAME/g" | sed "s/PROXYPATH/$PROXY_PATH/g" | sed "s/PROXYLOCATION/$PROXY_LOCATION/"

location_template.conf
    location /PROXYLOCATION {
        proxy_pass PROXYPATH;
    }

template.conf
server {
    server_name "HOSTNAME";

    ssl_certificate /etc/letsencrypt/live/HOSTNAME_BASE/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/HOSTNAME_BASE/privkey.pem;

    listen 443 ssl;

    keepalive_timeout 60;
    ssl on;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers "HIGH:!RC4:!aNULL:!MD5:!kEDH";
    add_header Strict-Transport-Security 'max-age=604800';
    proxy_set_header X-Forwarded-Server $host;
    proxy_set_header X-Forwarded-Host $host;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Real-IP $remote_addr;

    # set max upload size
    client_max_body_size 4000M;

    sendfile on;
    send_timeout 600s;
    proxy_connect_timeout 600;

    location /PROXYLOCATION {
        proxy_pass_request_headers on;
        proxy_pass_request_body on;
        proxy_pass PROXYPATH;
    }
}

, ./compile_apps_configs.sh nginx: sudo systemd reload nginx.


Docker


, docker docker-compose:


sudo apt install docker docker-compose


yml . :


โ”œโ”€โ”€ doForAll
โ”œโ”€โ”€ gogs
โ”‚   โ”œโ”€โ”€ docker-compose.yml
โ”‚   โ”œโ”€โ”€ Dockerfile
โ”‚   โ””โ”€โ”€ .env
โ”œโ”€โ”€ grafana
โ”‚   โ”œโ”€โ”€ configs
โ”‚   โ”‚   โ”œโ”€โ”€ influxdb.conf
โ”‚   โ”‚   โ””โ”€โ”€ telegraf.conf
โ”‚   โ”œโ”€โ”€ docker-compose.yml
โ”‚   โ””โ”€โ”€ .env
โ”œโ”€โ”€ jenkins
โ”‚   โ”œโ”€โ”€ docker-compose.yml
โ”‚   โ”œโ”€โ”€ .env
โ”œโ”€โ”€ makeFullUpdate
โ”œโ”€โ”€ radicale
โ”‚   โ”œโ”€โ”€ docker-compose.yml
โ”‚   โ””โ”€โ”€ .env
โ””โ”€โ”€ syncthing
    โ”œโ”€โ”€ docker-compose.yml
    โ””โ”€โ”€ .env

, ( grafana โ€” , โ€” influxdb). .


, :


  • .env DATA_PATH
  • Grafana - :
    • Telegraf. .env INFLUXDB_WRITE_USER_PASSWORD, configs/telegraf.conf โ€” password
    • Grafana. .env INFLUXDB_READ_USER_PASSWORD, Grafana


.


root. :


#    root
sudo -i
mkdir -p /root/scripts/
touch "/root/scripts/monitor_startup_docker_container"
chmod 700 "/root/scripts/monitor_startup_docker_container"
nano "/root/scripts/monitor_startup_docker_container"

/root/scripts/monitor_startup_docker_container :


#!/bin/bash

function log() {
    echo `date`: "$@"
}

container_name="$1"

true=1
false=0

function restartContainer() {
    docker container restart "$1"
}

function checkContanerExitStatus() {
    container_name="$1"
    status_line="`docker container ps -a --filter "name=$container_name" --filter "exited=255" | grep "$container_name"`"
    [[ -z "$status_line" ]] && echo $false || echo $true
}

function checkContanerStatusIsEqual() {
    container_name="$1"
    container_dest_status="$2"
    status_line="`docker container ps -a --filter "name=$container_name" --filter "status=$container_dest_status" | grep "$container_name"`"
    [[ -z "$status_line" ]] && echo $false || echo $true
}

function isRunning() {
    echo "`checkContanerStatusIsEqual "$container_name" "running"`"
}

while [[ "`isRunning`" != "$true" ]]; do
    log check cycle "$container_name"

    if [ "`checkContanerStatusIsEqual "$container_name" "exited"`" == "$true" -o "`checkContanerStatusIsEqual "$container_name" "dead"`" == "$true" ]; then
        log restart "$container_name"

        restartContainer "$container_name"
    fi

    if [[ "`isRunning`" -eq "$false" ]]; then
        sleep 5
    else
        sleep 120
    fi

done

log started "$container_name"


crontab . root:


`crontab -e`
@reboot rm /root/startup_docker_logs

1/10 * * * * /root/scripts/monitor_startup_docker_container telegraf >> /root/startup_docker_logs
2/10 * * * * /root/scripts/monitor_startup_docker_container influxdb >> /root/startup_docker_logs
3/10 * * * * /root/scripts/monitor_startup_docker_container grafana >> /root/startup_docker_logs
3/10 * * * * /root/scripts/monitor_startup_docker_container jenkins >> /root/startup_docker_logs
3/10 * * * * /root/scripts/monitor_startup_docker_container gogs >> /root/startup_docker_logs
1/10 * * * * /root/scripts/monitor_startup_docker_container radicale >> /root/startup_docker_logs
2/10 * * * * /root/scripts/monitor_startup_docker_container syncthing >> /root/startup_docker_logs


, , ููŠ ุงู„ู…ุชูˆุณุท โ€‹โ€‹ุŒ ู„ุง ุชูˆุฌุฏ ุตูŠุงู†ุฉ ุชู‚ุฑูŠุจู‹ุง. ู…ุง ู„ู… ูŠุชู… ุชู†ุงูˆู„ู‡ ููŠ ู‡ุฐู‡ ุงู„ู…ู‚ุงู„ุฉ:


  • ุชูƒูˆูŠู† ุงู„ูˆุตูˆู„ ุฅู„ู‰ SSHุงู„ุชูˆุช: ู‡ู†ุงูƒ ุนุฏุฏ ูƒุจูŠุฑ ู…ู† ุงู„ุฏุฑูˆุณ ุญูˆู„ ู‡ุฐุง ุงู„ู…ูˆุถูˆุน ุŒ ู‡ู†ุง ู…ุซุงู„ ู…ุน DigitalOcean
  • ุชูƒูˆูŠู† ุงู„ุฎุฏู…ุงุช ู†ูุณู‡ุง
  • ุดุฑุงุก ูˆุชูƒูˆูŠู† DNS ู„ู„ู…ุฌุงู„ุงุช

ุณุฃูƒูˆู† ุณุนูŠุฏุง ุจุงู„ุชุนู„ูŠู‚ุงุช ูˆุงู„ุชุนู„ูŠู‚ุงุช ุงู„ู…ููŠุฏุฉ.

Source: https://habr.com/ru/post/undefined/


All Articles