Блог-шпаргалка

Все статьи категории linux

Array
(
    [0] => Array
        (
            [id] => 1
            [img] => 2025/03/24/post_20250324.png
            [title] => LVM RAID уровня зеркало
            [category_id] => 1
            [description] => Я, как настоящий скуф, очень долго не хотел признавать всю гибкость и прелести разметки LVM, а может просто не хотел даже попробовать разметить таким образом диск, но лучше поздно, чем никогда и наконец-то я решился. Как в совковом к/ф - "Вий", открытые веки восторженно увидели все ништяки LVM. Скажу больше, вместо обычного mdadm raid-массива, я попробовал LVM RAID. О чём в принципе и будет эта статья. Предполагаю, что если ты это читаешь, то имеешь представление что это за технология, поэтому уровни абстракции и теорию опустим, а перейдём сразу к практике. Поехали…

Предварительно мы уже воткнули 2 HDD по соточке. Смотрим что там у нас есть.

lsblk
NAME      MAJ:MIN RM  SIZE RO TYPE MOUNTPOINTS
sr0        11:0    1 1024M  0 rom  
vda       254:0    0    8G  0 disk 
├─vda1    254:1    0  365M  0 part /boot
└─vda2    254:2    0  7.6G  0 part 
  └─vg-lv 253:0    0  7.6G  0 lvm  /
vdb       254:16   0  100G  0 disk 
vdc       254:32   0  100G  0 disk

Вот они, два маленьких засранца под именами vdb и vdc, которые нас интересуют.

Небольшое отступление - в сети есть куча холиваров, на тему "Надо ли создавать раздел на диске, если он будет использоваться весь?" Ребят, я Вам скажу, что надо! Ибо сам не сталкивался, но при подключении к другой системе, ОСь может посчитать, что он пустой и предложить создать раздел, да и вообще при таком раскладе можно проебать все данные, а экономия места, при отсутствии разделов — это килобайты.

Создаём разделы. Для разметки я предпочитаю использовать встроенные утилиты. Заюзаем fdisk

fdisk /dev/vdb
g
n
enter
enter
enter
t
43
w

Аналогичные действия проделываем со вторым диском.

Инициализируем диски

pvcreate /dev/vd[bc]1
root@test:/home/swapon# pvcreate /dev/vd[bc]1
  Physical volume "/dev/vdb1" successfully created.
  Physical volume "/dev/vdc1" successfully created.

Создаём группу томов именуя её как пожелаете.

vgcreate vgraid /dev/vd[bc]1
root@test:/home/swapon# vgcreate vgraid /dev/vd[bc]1
  Volume group "vgraid" successfully created

Ну и создаём логический диск RAID уровня зеркало

lvcreate --size 10G --name testm1 --mirrors 1 vgraid
root@test:/home/swapon# lvcreate --size 10G --name testm1 --mirrors 1 vgraid
  Logical volume "testm1" created.

Процесс создания можно наблюдать командой

lvs -a -o +devices
root@test:/home/swapon# lvs -a -o +devices
  LV                VG     Attr       LSize  Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert Devices                              
  lv                vg     -wi-ao----  7.64g                                                     /dev/vda2(0)                         
  testm1            vgraid rwi-a-r--- 10.00g                                    16.93            testm1_rimage_0(0),testm1_rimage_1(0)
  [testm1_rimage_0] vgraid Iwi-aor--- 10.00g                                                     /dev/vdb1(1)                         
  [testm1_rimage_1] vgraid Iwi-aor--- 10.00g                                                     /dev/vdc1(1)                         
  [testm1_rmeta_0]  vgraid ewi-aor---  4.00m                                                     /dev/vdb1(0)                         
  [testm1_rmeta_1]  vgraid ewi-aor---  4.00m                                                     /dev/vdc1(0)

и особое внимание необходимо обратить на колонку Cpy%Sync, в которой значение желательно должно быть 100, перед использованием диска.

Осталось создать файловую систему. Лично я использую православную ext4, так как плюсов от других особо не вижу.

mkfs.ext4 /dev/vgraid/testm1

и всё! Как говорят наши "друзья" из ближнего зарубежья: - "Ты красаушык Уася!"

Как будешь использовать логический диск уже сам решишь. Лично у меня они используются как блочное устройство для виртуальных машин

[status] => 1 [lastupdate] => 2025-03-24 ) [1] => Array ( [id] => 2 [img] => 2025/03/25/post_20250325.jpg [title] => PHP connect to DataBase [category_id] => 1 [description] => Уходят времена, когда процедурный стиль написания кода, в ненавистной всем пихе, играл ключевую роль. Конечно, на сегодняшний день, ещё очень много проектов работают на лютейшем легаси по разным причинам:
  1. Долбоёбы, которые придерживаются слогана: "Работает - не трогай!"
  2. Отсутствие компетентного разработчика в штате
  3. Скупое отношение руководства к персоналу
  4. Остальные причины более редкие

На моей практике частенько встречаются директора, которые разово нанимают по объявлению людей, которые делают сайты под ключ. Эти люди, по ю-тубовским видосам, разворачивают движок на джумле или вордпрессе или ещё хуже на тильде, прикручивают к нему скин, берут за это от 50-ти до 100 тысяч рублей и всё =) Естественно, когда что-то случается или необходимо внести какие-либо правки, эти горе-программисты разводят руками.

На сегодняшний день широкое применение и достойную нишу занял PDO (PHP Data Objects). Вышел он в свет в ноябре 2005 года с версией PHP 5.1.

В этом посте мы сперва набросаем, а потом разберём каждый параметр подключения к базе данных.

<?php

$host = 'localhost';
$db = 'Имя БД';
$usr = 'username';
$pwd = 'password';
$chrst = 'utf8';
$opt = [
	PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC];

$dsn = "mysql:host=$host;dbname=$db;charset=$chrst";

try {
	$dbconnect = new PDO($dsn, $usr, $pwd, $opt);
} catch (PDOException $e) {
	echo 'Ошибка: ' . $e->getMessage();
}

Сопсна в данном примере всё до безобразия примитивно и просто. Первые пять переменных опустим, так как в них и ежу понятно что происходит, а вот переменную opt прокомментирую. Параметр, указанный в ней, определяет метод выборки по умолчанию, а значение возвращает краткий результат в виде ассоциативного массива.

В переменной $dsn мы готовим строку подключения, ну и создаём сам объект подключения, используя конструкцию try-catch для того, чтоб если что неправильно, отловить ошибку

До выхода в свет 8-ой версии PHP, в параметрах подключения обязательно надо было использовать PDO::ATTR_ERRMODE со значением PDO::ERRMODE_EXCEPTION, но сейчас он используется по умолчанию и является необязательным.

[status] => 1 [lastupdate] => 2025-03-25 ) [2] => Array ( [id] => 3 [img] => 2025/03/26/post_20250326.jpg [title] => Установка Gentoo на шифрованный LVM [category_id] => 1 [description] => Проходя свой путь линуксойда, с 2017-го года и по сей день, я не мало сменил дистрибутивов и по итогу решил отнести себя к красноглазикам, остановившись на прекрасном Gentoo.

В этом посте я не буду пересказывать хэндбук, а покажу свою установку gentoo на шифрованный lvm раздел.

Погнали…

Сливаем Minimal Installation CD

Записываем на USB утилиткой dd, ну или если с винды, то руфус’ом

Грузимся...

Если планируется установка по ssh (что для копи/паста будет удобнее), то запускаем нужный демон

rc-service sshd start
ssh-keygen: generating new host keys: RSA ECDSA ED25519
* Starting sshd ...

И задаём пароль рута

passwd
New password:
Retype new password:
passwd: password updated successfully

Смотрим IP адрес

ip a

И подключаемся к хосту

Размечаем диск
У меня для показа это виртуалка, поэтому диск будет именоваться vda

fdisk /dev/vda

Размечаем под раздел /boot
g - для метки GPT
n - новый
enter - по умолчания первая партиция
enter - по умолчанию первый сектор
+384m - для хранения в /boot 3-х - 4-х ядер + initramfs этого хватает
t - тип файловой системы
1 - EFI

Размечаем под всё остальное
n - новый
enter - по умолчания вторая партиция
enter - по умолчанию следующий сектор после будущего раздела /boot
enter - всё оставшееся место
t - тип файловой системы
enter - по умолчанию следующий раздел
44 - Linux LVM

Отлично!

Вводим p и смотрим что получилось

Command (m for help): p
Disk /dev/vda: 50 GiB, 53687091200 bytes, 104857600 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: 6078AEC1-950E-4782-8F78-F3366C2ECA5D

Device      Start       End   Sectors  Size Type
/dev/vda1    2048    788479    786432  384M EFI System
/dev/vda2  788480 104855551 104067072 49.6G Linux LVM

Для сохранения изменений жмём w

Форматируем первый раздел в FAT32

mkfs.vfat -F32 /dev/vda1 
mkfs.fat 4.2 (2021-01-31)

Шифруем раздел под lvm.
Заглавными буквами пишем YES и вводим парольную фразу

cryptsetup -v -y -c aes-xts-plain64 -s 512 -h sha512 -l 5000 --use-random luksFormat /dev/vda2

WARNING!
========
This will overwrite data on /dev/vda2 irrevocably.

Are you sure? (Type ’yes’ in capital letters): YES
Enter passphrase for /dev/vda2: 
Verify passphrase: 
Key slot 0 created.
Command successful.

Можно полюбопытствовать характеристики шифра командой

cryptsetup luksDump /dev/vda2

Для продолжения установки открываем контейнер следующей командой

cryptsetup luksOpen /dev/vda2 gentoo

Так как у нас чистый диск для установки и вышеописанные действия заново разметили диск, мы знаем что у нас там и как, но для параноиков удостоверимся, что разделов LVM там нет

lvmdiskscan 
  /dev/live-base     [    <679.03 MiB] 
  /dev/mapper/gentoo [     <49.61 GiB] 
  /dev/vda1          [     384.00 MiB] 
  /dev/vda2          [      49.62 GiB] 
  2 disks
  2 partitions
  0 LVM physical volume whole disks
  0 LVM physical volumes

Создаём физическую группу томов, добавив в неё раздел под LVM

pvcreate /dev/mapper/gentoo
  Physical volume "/dev/mapper/gentoo" successfully created.

Смотрим подробности

pvdisplay
  "/dev/mapper/gentoo" is a new physical volume of "<49.61 GiB"
  --- NEW Physical volume ---
  PV Name               /dev/mapper/gentoo
  VG Name               
  PV Size               <49.61 GiB
  Allocatable           NO
  PE Size               0   
  Total PE              0
  Free PE               0
  Allocated PE          0
  PV UUID               pt0bn0-GezX-vcms-rf1C-4GOK-XvS1-OKzKCq>

Создаём группу томов, именуя её gentoo

vgcreate gentoo /dev/mapper/gentoo
  Volume group "gentoo" successfully created

Смотрим подробности

vgdisplay 
  --- Volume group ---
  VG Name               gentoo
  System ID             
  Format                lvm2
  Metadata Areas        1
  Metadata Sequence No  1
  VG Access             read/write
  VG Status             resizable
  MAX LV                0
  Cur LV                0
  Open LV               0
  Max PV                0
  Cur PV                1
  Act PV                1
  VG Size               <49.61 GiB
  PE Size               4.00 MiB
  Total PE              12699
  Alloc PE / Size       0 / 0   
  Free  PE / Size       12699 / <49.61 GiB
  VG UUID               QNly8N-7SgY-kznw-twHZ-Qis6-x7K6-eHP4oF

Создаём на всём свободном месте логический диск.

lvcreate -l +100%FREE gentoo -n root
  Logical volume "root" created.

Смотрим подробности

lvdisplay 
  --- Logical volume ---
  LV Path                /dev/gentoo/root
  LV Name                root
  VG Name                gentoo
  LV UUID                QX0NCa-BVwD-IiY7-p2BP-Mccm-4onj-jhock6
  LV Write Access        read/write
  LV Creation host, time livecd, 2025-03-25 02:16:27 +0000
  LV Status              available
  # open                 0
  LV Size                <49.61 GiB
  Current LE             12699
  Segments               1
  Allocation             inherit
  Read ahead sectors     auto
  - currently set to     256
  Block device           253:1

Для просмотра найденных групп томов используем vgscan

vgscan 
  Found volume group "gentoo" using metadata type lvm2

Для активации логических дисков

vgchange -ay
  1 logical volume(s) in volume group "gentoo" now active

Форматируем логический диск

mkfs.ext4 /dev/mapper/gentoo-root
mke2fs 1.47.2 (1-Jan-2025)
Creating filesystem with 13003776 4k blocks and 3252224 inodes
Filesystem UUID: ba9b3a00-be25-45c4-b8a9-985b59df09f2
Superblock backups stored on blocks: 
	32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208, 
	4096000, 7962624, 11239424

Allocating group tables: done                            
Writing inode tables: done                            
Creating journal (65536 blocks): done
Writing superblocks and filesystem accounting information: done

И монтируем его

mount /dev/mapper/gentoo-root /mnt/gentoo/

Удостоверяемся

lsblk /dev/vda
NAME            MAJ:MIN RM  SIZE RO TYPE  MOUNTPOINTS
vda             252:0    0   50G  0 disk  
├─vda1          252:1    0  384M  0 part  
└─vda2          252:2    0 49.6G  0 part  
  └─gentoo      253:0    0 49.6G  0 crypt 
    └─gentoo-root 253:1    0 49.6G  0 lvm   /mnt/gentoo

Переходим в примонтированную на прошлом шаге папку

cd /mnt/gentoo/

Скачиваем файлы для работы системы
Тут на вкус и цвет кто что хочет. Мой выбор desktop-openrc

links https://www.gentoo.org/downloads/mirrors

Распаковываем

tar xpvf stage3-amd64-desktop-openrc-20250322T105044Z.tar.xz --xattrs-include=’*.*’ --numeric-owner

Скопируем настройки DNS

cp --dereference /etc/resolv.conf /mnt/gentoo/etc/

Настраивим make.conf, приводя его к следующему виду

nano /mnt/gentoo/etc/portage/make.conf
CFLAGS="-march=native -O2 -pipe"
CXXFLAGS="${CFLAGS}"

ACCEPT_LICENSE="*"

LINGUAS="ru en"
L10N="ru en_US"

GENTOO_MIRRORS="https://mirror.yandex.ru/gentoo-distfiles/"

Сделаем индивидуальный файл, в котором описаны настройки для обновления

mkdir --parents /mnt/gentoo/etc/portage/gentoo.conf
cp /mnt/gentoo/usr/share/portage/config/repos.conf /mnt/gentoo/etc/portage/gentoo.conf/

Монтируем файловые системы
Параметр --make-rslave необходим для поддержки systemd в ходе установки. Я выбрал профиль openrc, в связи с чем, поддержка systemd мне нахуй не нужна

mount --types proc /proc /mnt/gentoo/proc
mount --rbind /sys /mnt/gentoo/sys
mount --rbind /dev /mnt/gentoo/dev
mount --bind /run /mnt/gentoo/run

Переходим в изолированное окружение и загрузим в память некоторые параметры прпофиля

chroot /mnt/gentoo /bin/bash
source /etc/profile

Монтируем первый раздел диска в папку /boot

mount /dev/vda1 /boot

Скачаем снимок репозитория

emerge-webrsync

Далее, для синхронизации с репозиторием пакетов gentoo, мы будем использовать git. Установим его

emerge --ask dev-vcs/git

Для удобства (конкретно мне) соберём и установим vim, но соберём мы его без излишеств. Cкажем протажу что нам не нужны в пакете звук и шифрование. До сих пор не могу понять где это может пригодиться

nano /etc/portage/package.use/vim
app-editors/vim -crypt -sound
emerge -av vim

Для дополнения по табу установим bash-comletion

emerge -av bash-completion

А теперь подредактируем наш индивидуальный конфиг. Заменим значение sync-type = rsync на git и sync-uri на https://github.com/gentoo/gentoo. Файл /etc/portage/repos.conf/gentoo.conf должен выглядеть примерно так

[DEFAULT]
main-repo = gentoo

[gentoo]
location = /var/db/repos/gentoo
sync-type = git
sync-uri = https://github.com/gentoo/gentoo
auto-sync = yes
sync-rsync-verify-jobs = 1
sync-rsync-verify-metamanifest = yes
sync-rsync-verify-max-age = 3
sync-openpgp-key-path = /usr/share/openpgp-keys/gentoo-release.asc
sync-openpgp-keyserver = hkps://keys.gentoo.org
sync-openpgp-key-refresh-retry-count = 40
sync-openpgp-key-refresh-retry-overall-timeout = 1200
sync-openpgp-key-refresh-retry-delay-exp-base = 2
sync-openpgp-key-refresh-retry-delay-max = 60
sync-openpgp-key-refresh-retry-delay-mult = 4
sync-webrsync-verify-signature = yes

Удалим, что скачал webrsync

rm -rf /var/db/repos/gentoo/

А теперь обновим дерево пакетов до самого актуального

emerge --sync

В переменной USE файла make.conf необходимо указать с чем собрать систему, а что выкинуть из неё. Я покажу свой пример.

YES="X x265"
NO="-bluetooth -bluray -cdda -cdr -cups -dvd -dvdr -gnome -ipv6 -kde -qt5 -qt6 -systemd -wayland -wext -wifi"
USE="$YES $NO"

А затем обновиться с новыми флагами

emerge -avuDN @world

Далее нам разово понадобится утилита cpuid2cpuflags для автоматического выбора флагов процессора

emerge --oneshot cpuid2cpuflags

Выхлопом команды echo создадим файл с необходимыми флагами

echo "*/* $(cpuid2cpuflags)" > /etc/portage/package.use/00cpu-flags

При настройке часового пояса, хуй знает почему, но симлинк локалтайма уже есть. Удалим его

rm /etc/localtime

Затем настроим часовой пояс. У меня это Владивосток

echo ’Asia/Vladivostok’ > /etc/timezone
emerge --config timezone-data

Настроим локали приведя файл locale.gen к следующему виду

vim /etc/locale.gen
en_US ISO-8859-1
en_US.UTF-8 UTF-8
ru_RU.UTF-8 UTF-8

И сгенерируем их

locale-gen

Посмотрим какие теперь присутствуют

eselect locale list

Выберем необходимую

eselect locale set <номер>

Перезагрузим окружение

env-update && source /etc/profile

Ставим исходники

emerge -av gentoo-sources

И необходимые пакеты для сборки и старта системы

vim /etc/portage/package.use/sudo
app-admin/sudo -sendmail
vim /etc/portage/package.use/lvm
sys-fs/lvm2 lvm
emerge -av sudo lvm cryptsetup genkernel

Сгенерируем fstab. Я предпочитаю идентифицировать накопители по UUID и делаю это извращённо

blkid > /etc/fstab

Затем оставляю необходимые UUID и добавляю точку монтирования с параметрами. На выходе должно получиться примерно так

UUID=BE2B-3600					/boot	vfat	noatime				0 2
UUID=ba9b3a00-be25-45c4-b8a9-985b59df09f2	/	ext4	rw,relatime,data=ordered	0 1

В конфиге генкернела включим lvm и шифрование

vim /etc/genkernel.conf
LVM="yes"
LUKS="yes"

Выбираем ядро

eselect kernel set 1

Конфигурация ядра - это одна большая тема. Сами делайте =)

Собираем initramfs

genkernel --lvm --luks initramfs

Добавляем необходимые параметры перед установкой загрузчика

vim /etc/portage/package.use/grub
sys-boot/grub device-mapper mount

И собираем его

emerge -av grub

Говорим грабу как надо грузиться
Я ещё выключил ipv6

vim /etc/default/grub
# Append parameters to the linux kernel command line
GRUB_CMDLINE_LINUX="ipv6.disable=1 crypt_root=UUID=5e4f0cfa-ec51-435b-8340-63f8ef332dc8 root=/dev/mapper/root-root rootfstype=ext4 dolvm quiet"

Устанавливаем его

grub-install --target=x86_64-efi --efi-directory=/boot /dev/vda

Генерируем сам файл загрузки

grub-mkconfig -o /boot/grub/grub.cfg

Ставим пароль на рута

passwd

Создаём обычного пользователя и добавляем его в необходимые группы

useradd -m -G audio,video,users,wheel -s /bin/bash username

Задаём ему парольную фразу

passwd username

Добавляем старт lvm при загрузке

rc-update add lvm boot

Выходим и рестартуемся

exit
cd
reboot

Неуверен, что генту будет использоваться на сервере. Скорее на десктопе. В связи с чем необходимо накатить иксы ну и любимую DE. Заебенем это в следующих постах!

[status] => 1 [lastupdate] => 2025-03-26 ) [3] => Array ( [id] => 4 [img] => 2025/03/28/post_20250328.png [title] => Docker. Большая шпаргалка. (Пополняемая) [category_id] => 1 [description] =>

Я всегда предпочитал работать только с теми сервисами и инструментами, которые чаще всего встречаются в моей практике. В связи с чем docker очень долгое время оставался неизученным. Лишь поверхностные знания рисовали какую-то картину для чего он нужен.

Настал тот день, когда docker понадобился хотя бы для того, чтоб развернуть офисные инструменты для клауда.

Работая в крупной компании, при которой целая академия и умнючий сука и компетентный препод с редким именем Лев, я осилил его курс от 2024 года и для себя набросал шпаргалку, которую оформляю ниже и сразу же подчеркну, что в этом посте будут только команды. Никакого compose тут нет.

Погнали…

Как всегда начинаем с установки используя пакетный менеджер. У меня это emerge

sudo emerge -av app-containers/docker app-containers/docker-cli

По требованиям информационной безопасности, добавим своего пользователя в группу docker

sudo usermod -aG docker username

Ну и стартанём сервис + добавим его в автозапуск

sudo rc-service docker start
sudo rc-update add docker default

Много чего интересного можно увидеть по следующей команде, да и вообще перед стартом работы

docker info

А теперь перейдём непосредственно к командам

Одно из главных правил запуска контейнеров - опции (ключи) необходимо указывать ДО ИМЕНИ ОБРАЗА

docker run имя - запуск контейнера

По правилам хорошего тона, при запуске контейнера, всегда, после двоеточия надо указывать версию имени и через дефис ОСь контейнера, но не в коем случае блять не использовать latest. Для примера возьмём с докерхаба nginx версии 1.27.4, собранный на alpine 3.21
docker run nginx:1.27.4-alpine3.21-slim - это правильное радио

Запустив таким образом контейнер, он займёт терминал и мы нечего не сможем сделать. Для запуска контейнера в фоне, добавим ему ключ -d
docker run -d nginx:1.27.4-alpine3.21-slim

При запуске контейнера, докер присваивает ему имя от балды. Поэтому имя лучше всего присваивать самому.
docker run --name nginx -d nginx:1.27.4-alpine3.21-slim - ещё идеальное радио

Для разового запуска контейнера, чтоб после установки он удалился, добавим ключ --rm
docker run --rm --name nginx -d nginx:1.27.4-alpine3.21-slim

Для доступа к приложению в контейнере на определённом порту, необходимо добавить опцию -p с портом, на который стучимся и через двоеточие - порт приложения. Таким образом порт (пример) 8081, на всех интерфейсах хоста, будет перенаправлять трафик в контейнер на порт (пример) 80
docker run --rm -p 8081:80 --name nginx nginx:1.27.4-alpine3.21-slim

От запущенной команды выше, информационная безопасность может Вас попросту отпиздить. Поэтому, в целях безопасности, необходимо ограничивать IP адресом приложение
docker run --rm -p 127.0.0.1:8081:80 --name nginx nginx:1.27.4-alpine3.21-slim

Чтоб выполнить команду внутри контейнера
docker exec nginx ps

Для того, чтобы поковыряться внутри контейнера
docker exec -ti nginx /bin/sh

Полезно будет дебажить приложение, добавив параметр --entrypoint
docker run --rm -p 127.0.0.1:8081:80 --name nginx -ti --entrypoint /bin/sh nginx:1.27.4-alpine3.21-slim
таким образом мы провалимся в контейнер не запуская ничего

Для того, чтоб после запуска сразу провалиться в контейнер
docker run --rm -ti ubuntu:24.04

Контейнеры

docker ps - список запущенных контейнеров
docker ps -a - список всех контейнеров, включая остановленные
docker run - запуск контейнера
docker run -d - запуск контейнера в фоне
docker run --name имя - присвоить имя контейнеру
docker run --rm - удалить контейнер после его остановки
docker restart id или имя - перезапустить контейнер
docker stop id - остановка контейнера
docker stop $(docker ps -q) - остановка всех запущенных контейнеров
docker inspect id - вся подноготная контейнера в json формате
docker exec имя контейнера команда - выполнить команду внутри контейнера
docker exec -ti имя контейнера /bin/sh - запустить терминал внутри контейнера
docker exec -ti имя контейнера --entrypoint /bin/sh - запустить контейнера без запуска служб
docker rm id - удалить контейнер

Образы

docker image list - список образов
docker image prune -a - удаляет образы, с которыми не связан ни один контейнер

Сеть

Существуют несколько способов организации сети в docker

bridge
Способ по умолчанию
Создается пара veth-адаптеров, один в контейнер, другой в bridge на хосте

none
Никакой сети для контейнера не будет
Рекомендуется просто для вычислительной задачи (транскод видео, обработка картинок) с пробросом в него директории с хоста

host
Контейнер будет использовать сеть хостовой машины не создавая сетевой namespace. При таком варианте производительность будет максимальная

overlay
Сеть (VxLAN) между хостами. Применяется для Swarm

macvlan
Реальный сетевой адаптер между контейнерами

ipvlan
Практически нигде не используется

docker network ls - просмотр существующих сетей
docker network create имя_сети - создаём сеть с именем test1 (по умолчанию bridge)
docker network inspect имя_сети - просмотр подноготной сети
docker run --net имя_сети - запуск контейнера в определённой сети
docker run -p 8081:80 имя образа - доступ к приложению на порту 8081
docker run -p 127.0.0.1:8081:80 имя образа - доступ к приложению на локальном IP и порту 8081

Для примера запустим ubuntu в созданной сети с именем test1 сети
docker run --rm -ti --net test1 ubuntu:24.04

Логи
Располагаются по пути /var/lib/docker/containers/id-контейнера

Во избежание разрастания лога, настроим ротацию, добавим в файл /etc/docker/daemon.json следующий параметры:

"log-opts":{
	"max-size": "50m",
	"max-file": "3"
}

docker logs id - просмотр логов контейнера. Без донастройки логирования выше, лог может со временем стать внушительного размера
docker logs -n50 id-контейнера - последние 50 строк лога

[status] => 1 [lastupdate] => 2025-04-02 ) )