Za górami, za lasami…
…żył Adrianek z głupimi pomysłami. I pewnego dnia ulepił playbook w Ansible, bo przecież nie będzie jak zwierzę jakieś aktualizacji instalować z łapy. Więc minut kilka później Ansible w środowisku testowym wykonał robotę, nie przewrócił nic, więc został utworzony plik z hostami produkcyjnymi.
Ależ to był debilny pomysł, pomyślał Adrianek, wywalając maszynę w kosmos…
Cóż to była za maszyna? A kontener LXC ze wsi Proxmox, z wybudowanymi delikatesami WordPress i MariaDB. I tak sobie to działało i było dobrze.
No, do momentu, gdy taki kontener dostał strzała z tsunami apt-update i apt-upgrade i nastał bałagan z uprawnieniami. Jednocześnie to historia pełna sprzątania błędów młodości, łez, przyśpiewek, żartów i wybitnie wysokiego poziomu. Zabawa gwarantowana, polecam, jeśli życie za mało kopie po jajkach.
…hej górale nie bijta się
Właściwie co to za pierdolenie głupot, jakie uprawnienia, jaki śmietnik, Ziomuś, to zwykły apdejt a ty wyjeżdżasz z jakimiś historiami z innej planety!
No właśnie jednak coś się podziało. Niestety nie jestem w stanie wskazać konkretnej przyczyny, ale jestem w stanie opisać cały proces namierzania obszaru z problemem, sposobu na ominięcie tegoż, a także udaną próbę startu serwera WWW i jego bazy danych na innym środowisku.
Początkowo, będąc jeszcze zalogowanym (w trakcie i bezpośrednio po aktualizacji) przez SSH do kontenera LXC, otrzymałem powiadomienie z Uptime Kuma:

Pomyślałem sobie: poszedł update Dockera, czasami trzeba ręcznie podnieść kontenerek tego walenia patentowanego, zdarza się. Jakież było moje zdziwienie, gdy dostałem na twarz czymś takim:
WażnyUser@serwer-www:~# docker start portainer_agent Error response from daemon: failed to create task for container: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: error during container init: open sysctl net.ipv4.ip_unprivileged_port_start file: reopen fd 8: permission denied failed to start containers: portainer_agent
Szybki disklejmer: zanim jakiś geniusz mi zarzuci, że mówię o WordPressie a wklejam portaner-agent, to tłumaczę: chciałem wyklikać to w Portainerze, ale z jakiegoś powodu agent leżał i udawał Rejtana. Potem dowiedziałem się, co to za koszula zaczęła być darta…
Poszedłem na skróty i postanowiłem ten kontener LXC w Proxmoxie uruchomić testowo z wyłączonymi kagańcami. W Proxmoxie te parametry zostały przestawione na zrzucenie kagańców

Niestety, nie pomogło. Sprawdziłem także apparmor, SE Linux (czy nie poleciała konfiguracja, nie włączyło się coś, czy coś nie wybuchło i w ogóle jaki bałagan).
Nic nie zwiastowało jednak wesołej kontynuacji. Od tego momentu zacząłem wspomagać się ChatGPT w formie kolegi z biurka obok.
Ta cała sztuczna inteligencja przejmie nad nami kontrolę!
Oczywiście nie polegałem na tym narzędziu jak na prawdzie objawionej. Muszę już na początku to powiedzieć: ChatGPT miał ogromną tendencję do zaorania całości i postawienia aplikacji na nowo, tracąc jednocześnie dane. Z oczywistych powodów wybrałem bramkę numer dwa. Czyli rzeźba w gównie.
Sprawdziłem także, czy posadzenie wewnątrz kontenera LXC kolejnego Dockerka, tym razem świeżutki i niewiele robiący Linux Alpine się uruchomi. Nie, nie uruchomi. Błąd jak wcześniej:
WażnyUser@serwer-www:~/jakis_katalog# docker run --rm --privileged alpine cat /proc/sys/net/ipv4/ip_unprivileged_port_start
Unable to find image 'alpine:latest' locally
latest: Pulling from library/alpine
2d35ebdb57d9: Pull complete
Digest: sha256:4b7ce07002c69e8f3d704a9c5d6fd3053be500b7f1c69fc0d80990c2ad8dd412
Status: Downloaded newer image for alpine:latest
docker: Error response from daemon: failed to create task for container: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: error during container init: open sysctl net.ipv4.ip_unprivileged_port_start file: reopen fd 8: permission denied
Na tym etapie sprawdziłem, czy mam wjazd z poziomu CLI Proxmox do katalogów kontenera LXC. Sprawdziłem zatem w katalogu cd /etc/pve/lxc/ zawartość pliku związanego z kontenerem LXC:

Zwróć uwagę na linijkę rootfs. To było to! Szybka inspekcja tego zasobu:

Postanowiłem zatem ten zasób podmontować:
mount /dev/SSD/vm-104-disk-0 test/
Pozwoliło mi to buszować w strukturze systemu plików kontenera.
W tym miejscu dałem tej patologii jeszcze jedną szansę i sprawdziłem, jak wygląda plik konfiguracyjny SSH. Patologią nazwałem to nieprzypadkowo. Mój plik został zaorany jakąś domyślną wersją i w trakcie próby połączenia przez SSH host bardzo chciał otrzymać hasło, które nie było nigdy ustawione, gdyż skonfigurowane są jedynie klucze. Hasła to zło.
Dlaczego na tym etapie nie użyłem jeszcze pct? Jakby to powiedzieć…
root@proxmox:~# pct enter 104
bash: /root/.bashrc: Permission denied
root@serwer-www:~# ls -al
ls: cannot open directory '.': Permission denied
To był moment, w którym uznałem, że nie będę tego ratować i trzeba przenieść całość na inne środowisko. Prawdziwa maszyna wirtualna, prawdziwe zasoby, pozytywny przekaz i pozytywne myślenie.
Myślę pozytywnie, lekarz kazał myśleć pozytywnie
Myślę pozytywnie, nic mnie nie wkurwi dzisiaj
Idę, po prostu idę, spacer to dobry zwyczaj
Wdech i kurwa wydech, i do dziesięciu zliczam
Graj muzyko
Docker ma taką fajną cechę, że jego kontenery są całkiem przenośne. I nawet, jak aplikacja leży, da się to przenieść i liczyć, że zadziała to na nowym środowisku. Nie jest to poradnik jak pozbierać udupione środowisko, ale mam nadzieję, że chociaż jednej osobie to pomoże.
W moim przypadku aplikacja, w postaci Serwera WWW i jego bazy danych składała się w sumie z trzech lokalizacji:
– jakaś losowa lokalizacja z plikiem docker-compose.yml
– /var/lib/docker/volumes/wordpress_db
– /var/lib/docker/volumes/wordpress_app
Spakowałem je zatem, jak mi podpowiedział tutaj ładnie Pan GPT, cały ten burdel do 3 archiwów tar.gz:
cd /var/lib/docker/volumes/
tar czvf /root/wordpress_db.tar.gz wordpress_db
tar czvf /root/wordpress_app.tar.gz wordpress_app
cd /ta/dziwna/lokalizacja/do/compose/
tar czvf /root/wordpress_compose.tar.gz wordpress_compose
I wyprowadziłem całość za pomocą SCP na swoim komputerze:
scp root@IP_tej_maszyny:/root/*.tar.gz .
I to był koniec rozdziału pierwszego, a dane były zabezpieczone.
Świeże środowisko, świeże problemy
Ta noga skacze mi wyłącznie z muzycznych kurwa względów
Ludzie są cudowni, więc ciepło myślę o nich
W tym miejscu utworzyłem nową maszynę wirtualną, nadałem jej ten sam adres IP, co poprzedniemu kontenerowi LXC i zainstalowałem za pomocą tego złotego skryptu świeżego i pachnącego Dockera. Oczywiście jeszcze konfiguracja SSH, klucze, passwordless, systemctl restart, statyczne IP i wio. A, no i zmiana typu CPU na Host. To rozwiązuje kilka problemów.

Na nową maszynę wysłałem radośnie utworzone backupy:
scp ./*.tar.gz root@IP_Maszyny_Tajne:/root/
I ponownie na nową VM się zalogowałem. Utworzyłem katalog dla Docker Compose i rozpakowałem tam pierwsze archiwum:
tar xzvf /root/wordpress_compose.tar.gz
Następnie skopiowałem dwa pozostałe archiwa do /var/lib/docker/volumes/ i je tam rozpakowałem
mv /root/wordpress_db.tar.gz /var/lib/docker/volumes/
mv /root/wordpress_app.tar.gz /var/lib/docker/volumes/
cd /var/lib/docker/volumes/
tar xzvf /var/lib/docker/volumes/root/wordpress_db.tar.gz
tar xzvf /var/lib/docker/volumes/root/wordpress_app.tar.gz
Dlaczego nie wypakowałem tego tam od razu? Nie interesuj się, bo kociej mordy dostaniesz.
Przypominam tym, co jeszcze czytają: to jest Linux. Tu są uprawnienia, to trzeba dobrze skonfigurować. A to mnie ugryzło w dupę. I to boleśnie.
W logach związanych z bazą danych generowały mi się błędy:
2025-11-12T18:54:39.965184Z 0 [Warning] [MY-010091] [Server] Can't create test file /var/lib/mysql/mysqld_tmp_file_case_insensitive_test.lower-test
2025-11-12T18:54:39.965263Z 0 [System] [MY-010116] [Server] /usr/sbin/mysqld (mysqld 8.0.44) starting as process 1
2025-11-12T18:54:39.967524Z 0 [Warning] [MY-010091] [Server] Can't create test file /var/lib/mysql/mysqld_tmp_file_case_insensitive_test.lower-test
2025-11-12T18:54:39.967530Z 0 [Warning] [MY-010159] [Server] Setting lower_case_table_names=2 because file system for /var/lib/mysql/ is case insensitive
2025-11-12T18:54:39.967741Z 0 [Warning] [MY-010122] [Server] One can only use the --user switch if running as root
mysqld: File './binlog.index' not found (OS errno 13 - Permission denied)
W DockerCompose.yml miałem linijki, które określały z jakim UID i GID ma się to wszystko uruchomić:
user: "1001:1001"
I takie też uprawnienia nadałem całości nowo skopiowanych volumenów (tak też Pan GPT mi podpowiadał, więc to musiała być prawda):
sudo chown -R 1001:1001 /var/lib/docker/volumes/wordpress_db/_data
sudo chmod -R 750 /var/lib/docker/volumes/wordpress_db/_data
sudo chown -R 1001:1001 /var/lib/docker/volumes/wordpress_app/_data
sudo chmod -R 750 /var/lib/docker/volumes/wordpress_app/_data
Niespodzianka: z jakiegoś niewyjaśnionego powodu nie zadziałało. Nie ukrywam, powinno, ale nie analizowałem tego dalej. Postanowiłem testowo nieco zdjąć kagańce, które za jakiś czas założę z powrotem, gdy dowiem się do cholery ciężkiej jest zjebane.
Debuguj kolego, debuguj przyjacielu i nie denerduj mnie
W htop zauważyłem, że Docker usilnie uruchamia proces bazy danych z Usera 999:

Co zrobiłem? PRZEKLIKAŁEM JAK OSTATNI OSIOŁ ŁAJZOWATY NOOB NIEDOEKSPIONY DZIEWIĘĆDZIEWIEĆDZIEWIĘĆ DO CHMODA I CHOWNA JAKBY JUTRA MIAŁO NIE BYĆ i niczego nie żałuję, bo wyparłem to ze świadomości:
sudo chown -R 999:999 /var/lib/docker/volumes/wordpress_db/_data
sudo chmod -R 750 /var/lib/docker/volumes/wordpress_db/_data
sudo chown -R 999:999 /var/lib/docker/volumes/wordpress_app/_data
sudo chmod -R 750 /var/lib/docker/volumes/wordpress_app/_data
Mechanizm wyparcia okazał się skuteczny, bo aplikacja wstała i działa. I logi wyglądają ładnie. I ludzie są szczęśliwsi jakoś. I jakoś tak się weselej zrobiło. I żona jakoś tak ładniej na mnie spogląda. I słuchawki ładniej grają. Same zalety.
Podsumowań czas
Aplikacja działa, wszystko jest na pierwszy rzut oka świetne. Ale wnioski nie są takie kolorowe:
– czeka mnie dalsza rzeźba w gównie i debugowanie CO SIĘ DO CHOLERY ZESRAŁO
– sprawdzanie, dlaczego pomimo wskazywania usera w DockerCompose.yml Docker nadal na siłę startuje z innymi użytkownikami
– głębsze poznanie LXC. Trzeba swojego wroga poznać w końcu, nie?
Cały proces zajął mi około 3h grubego myślenia i zbierania faktów. Najśmieszniejsze jest to, że każdy pojedynczy proces jest doskonale mi znany, ale całość sprawiła mi trochę trudności. To dowód na to, że w sumie wiedza to jest jeden z elementów potrzebnych do naprawienia czegoś, co się zesrało, ale piekielne ważne jest doświadczenie i opanowanie nerwów. Także umiejętność korzystania z AI jest BARDZO pomocna, ale nie można ślepo podążać za jej instrukcjami, bo pomimo złotych promptów można otrzymać polecenie będące złotym enterem.
Czy temat jest zamknięty? Absolutnie nie. Działa, ale nie wiem do końca co poszło nie tak. Chciałbym uniknąć takiego czegoś, szczególnie jeśli jest to spowodowane moim błędem, którego jeszcze nie widzę.
Źródła
- cytaty są treścią piosenki Sokół i Marysia Starosta – Myśl pozytywnie https://www.youtube.com/watch?v=I7Pl9vevoGc
1 komentarz
LAB Przymusowy part 2: Sprzątanie w uprawnieniach – Baremetal.work · 13/11/2025 o 17:13
[…] poprzednim wpisie opisałem proces domowego disaster recovery. Aplikacja tam uruchomiona wstała, została w […]