VPS dla początkujących cz. 4: Gitea, Nextcloud i Dokuwiki

Napisano dnia 30.07.2021 r. o godzinie 7:00
Autor: Piotr Sperka

Wstęp

Cześć, witam Cię w czwartym odcinku serii pod tytułem VPS dla początkujących. Jak dotąd uruchomiliśmy na Dockerze nasze pierwsze usługi, a także skonfigurowaliśmy obsługę subdomen i SSL przy pomocy reverse proxy opartego o Nginx. Dzisiaj zajmiemy się uruchomieniem kolejnych trzech usług. Będą to kolejno:

  • Gitea, czyli GIT wraz z interfejsem webowym ułatwiającym tworzenie i zarządzanie repozytoriami. Początkowo myślałem o użyciu GitLaba, jednak na potrzeby prywatnego repozytorium byłoby to strzelanie z armaty do muchy.
  • Dokuwiki, czyli prosta wiki, która swoje działanie opiera na bazie w formie plików (nie potrzebuje bazy danych). Jest bardzo prosta w konfiguracji i obsłudze. Moim zdaniem będzie to idealne rozwiązanie na potrzeby prywatnej wiki.
  • Nextcloud, czyli usługa umożliwiająca przechowywanie i współdzielenie plików (coś jak Google Drive, OneDrive albo iCloud). Dodatkowo na Nextcloudzie można instalować wtyczki, czy też aplikacje, takie jak na przykład kalendarz, klient mailowy, książka kontaktów, notatnik, itp. Dzięki temu Nextcloud może stać się codziennym, osobistym niezbędnikiem.

Oczywiście, zgodnie z przyjętą w tej serii filozofią, wszystkie te usługi uruchomimy na Dockerze. W całym poniższym opisie założyłem, że operujesz z poziomu konta roota. Przejdźmy zatem do dzieła.

Gitea

Jak przy każdej nowej usłudze uruchamianej na Dockerze, zaczynamy od stworzenia katalogu w którym będą jej pliki. Tworzymy katalog /docker/gitea. Przygotowujemy rekord CNAME dla Gitei, na przykład gitea.twoja-domena.pl. Tworzymy plik docker-compose.yml:

version: '3.5'
services:
  gitea-web:
    image: gitea/gitea:latest
    volumes:
      - /docker/gitea/data:/data
    depends_on:
      - gitea-db
    restart: always
    environment:
      - USER_UID=1000
      - USER_GID=1000
      - GITEA__database__DB_TYPE=mysql
      - GITEA__database__HOST=gitea-db:3306
      - GITEA__database__NAME=gitea
      - GITEA__database__USER=gitea
      - GITEA__database__PASSWD=bardzotajnehaslo
    expose:
      - 3000
    networks:
      - reverse_proxy
  gitea-db:
    image: mariadb:latest
    restart: always
    environment:
      - MYSQL_RANDOM_ROOT_PASSWORD='1'
      - MYSQL_DATABASE=gitea
      - MYSQL_USER=gitea
      - MYSQL_PASSWORD=bardzotajnehaslo
    volumes:
      - /docker/gitea/mysql:/var/lib/mysql
    networks:
      - reverse_proxy
networks:
  reverse_proxy:
    external: true

Jak widzisz w powyższym pliku, korzystamy z oficjalnego obrazu Gitei z Docker Huba w wersji latest oraz z bazy MariaDB, również w najnowszej wersji. Zmienne środowiskowe ustawiłem zgodnie z dokumentacją instalacji Gitei. Teraz nadchodzi ważna uwaga. Jeżeli pozwolimy Dockerowi stworzyć katalog /docker/gitea/data, będzie miał on złe uprawnienia (jego właścicielem będzie root). W takim wypadku musisz zmienić mu właściciela poleceniem chown 1000:1000 /docker/gitea/data. Można również przed uruchomieniem docker-compose stworzyć ten katalog ręcznie, i zawczasu nadać mu odpowiednie uprawnienia:

mkdir /docker/gitea/data
chown 1000:1000 /docker/gitea/data

Jest to związane z tym, że aplikacja wewnątrz kontenera uruchomiona jest przez użytkownika posiadającego uid:gid = 1000:1000. W takim wypadku, po zamontowaniu katalogu należącego do roota, aplikacja nie będzie miała do niego dostępu. Zgodnie z dokumentacją, aplikacja Gitea posiada interfejs webowy wystawiony na porcie 3000 (dlatego eksponujemy ten port tagiem expose). Jest to ważna informacja, żeby dobrze ustawić przekierowanie reverse proxy. Teraz możemy uruchomić aplikację poleceniem docker-compose up -d i przejść do konfiguracji reverse proxy. Edytujemy plik nginx.conf, dodając nową sekcję server:

server {
    server_name gitea.twoja-domena.pl;

    location / {
      include /etc/nginx/includes/proxy.conf;
      proxy_pass http://gitea-web:3000;
    }

    listen 443 ssl;
    ssl_certificate /etc/letsencrypt/live/twoja-domena.pl/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/twoja-domena.pl/privkey.pem;
  }

Zapisujemy i przeładowujemy kontener z reverse proxy: docker-compose restart.

Teraz pod ustawionym adresem (na przykład gitea.twoja-domena.pl) powinna być dostępna Gitea. Przechodzimy konfigurację (między innymi podmieniamy domenę na taką, jaka jest skonfigurowana) i następnie rejestrujemy użytkownika. Użytkownik ten zostanie administratorem. Następnie edytujemy plik /docker/gitea/data/gitea/conf/app.ini. U siebie zmodyfikowałem sekcje server, service i openid, oraz dopisałem sekcję api. Plik nie jest długi i łatwo się w nim zorientować. Więcej informacji o ustawieniach można znaleźć tutaj.

[server]
APP_DATA_PATH    = /data/gitea
DOMAIN           = gitea.twoja-domena.pl
SSH_DOMAIN       = localhost
HTTP_PORT        = 3000
ROOT_URL         = https://gitea.twoja-domena.pl/
DISABLE_SSH      = true
SSH_PORT         = 22
SSH_LISTEN_PORT  = 22
LFS_START_SERVER = true
LFS_CONTENT_PATH = /data/git/lfs
LFS_JWT_SECRET   = tutajbedziejakisdlugitajnykod
OFFLINE_MODE     = false

[service]
DISABLE_REGISTRATION              = true
REQUIRE_SIGNIN_VIEW               = true
REGISTER_EMAIL_CONFIRM            = false
ENABLE_NOTIFY_MAIL                = false
ALLOW_ONLY_EXTERNAL_REGISTRATION  = false
ENABLE_CAPTCHA                    = false
DEFAULT_KEEP_EMAIL_PRIVATE        = false
DEFAULT_ALLOW_CREATE_ORGANIZATION = true
DEFAULT_ENABLE_TIMETRACKING       = true
NO_REPLY_ADDRESS                  = noreply.localhost

[openid]
ENABLE_OPENID_SIGNIN = false
ENABLE_OPENID_SIGNUP = false

[api]
ENABLE_SWAGGER = false

Po tym zapisujemy plik i restartujemy usługę poleceniem docker-compose restart. Teraz już nie ma możliwości samodzielnej rejestracji i tylko administrator może dodać nowe konto. Wyłączone jest logowanie poprzez Openid, a także wyłączony został Swagger, umożliwiający podgląd API.

Dokuwiki

Przejdźmy teraz do uruchomienia Dokuwiki. Tak samo jak wcześniej, korzystamy z obrazu udostępnionego na Docker Hubie. Zgodnie z dostępną tam dokumentacją, tworzymy plik docker-compose.yml, który umieszczamy w uprzednio utworzonym katalogu /docker/dokuwiki.

version: '3.5'
services:
  dokuwiki:
    image: docker.io/bitnami/dokuwiki:latest
    expose:
      - 8080
    volumes:
      - /docker/dokuwiki/data:/bitnami/dokuwiki
    networks:
      - reverse_proxy
networks:
  reverse_proxy:
    external: true

Podobnie jak w przypadku Gitei, również trzeba zmienić uprawnienia katalogu z danymi. Przed uruchomieniem kontenera wykonujemy:

mkdir /docker/dokuwiki/data
chown 1001 /docker/dokuwiki/data

Tym razem polecenie jest nieco inne, gdyż zmieniamy jedynie uid właściciela, gid pozostawiamy bez zmian. Warto odnotować, że tym razem aplikacja działa na porcie 8080, co przyda się podczas konfiguracji reverse proxy. Uruchamiamy kontener poleceniem docker-compose up -d. Teraz pozostało jeszcze zmodyfikować plik nginx.conf w reverse proxy, dodając kolejną sekcję server (oraz dodać kolejny rekord CNAME do konfiguracji DNS):

server {
    server_name wiki.twoja-domena.pl;

    location / {
      include /etc/nginx/includes/proxy.conf;
      proxy_pass http://dokuwiki:8080;
    }

    listen 443 ssl;
    ssl_certificate /etc/letsencrypt/live/twoja-domena.pl/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/twoja-domena.pl/privkey.pem;
  }

Na koniec restartujemy Nginxa poleceniem docker-compose restart i powinniśmy mieć dostępne wiki pod ustawionym adresem.

Nextcloud

Na koniec zajmiemy się postawieniem Nextclouda. Jak za każdym razem, tworzymy katalog – tym razem /docker/nextcloud – i w nim umieszczamy plik docker-compose.yml:

version: '3.5'

services:
  nextcloud-db:
    image: mariadb:latest
    restart: always
    command: --transaction-isolation=READ-COMMITTED --binlog-format=ROW
    volumes:
      - /docker/nextcloud/mysql:/var/lib/mysql
    environment:
      - MYSQL_RANDOM_ROOT_PASSWORD='1'
      - MYSQL_PASSWORD=tajnehaslo123
      - MYSQL_DATABASE=nextcloud
      - MYSQL_USER=nextcloud
    networks:
      - reverse_proxy

  nextcloud-app:
    image: nextcloud:latest
    restart: always
    expose:
      - 80
    links:
      - nextcloud-db
    volumes:
      - /docker/nextcloud/html:/var/www/html
    environment:
      - MYSQL_PASSWORD=tajnehaslo123
      - MYSQL_DATABASE=nextcloud
      - MYSQL_USER=nextcloud
      - MYSQL_HOST=nextcloud-db
    networks:
      - reverse_proxy

networks:
  reverse_proxy:
    external: true

Standardowo, korzystamy z najnowszych wersji MariaDB i Nextcloud z Docker Huba. Zmienne środowiskowe ustawiłem zgodnie z dokumentacją instalacji Nextcloud. Musisz mieć na uwadze, że zgodnie z tą konfiguracją, w katalogu /docker/nextcloud/html będą przechowywane również pliki użytkowników. Z tego powodu musi on być umieszczony na dysku z odpowiednią ilością miejsca. Oczywiście, odnosi się to tylko do przypadku konfiguracji z wieloma dyskami/partycjami. Teraz wykonujemy polecenie docker-compose up -d. Konfigurujemy odpowiedni rekord CNAME i dodajemy kolejny blok server do /docker/nginx-proxy/nginx.conf:

server {
    server_name nextcloud.twoja-domena.pl;

    location / {
      include /etc/nginx/includes/proxy.conf;
      proxy_pass http://nextcloud-app:80;
    }

    listen 443 ssl;
    ssl_certificate /etc/letsencrypt/live/twoja-domena.pl/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/twoja-domena.pl/privkey.pem;
  }

Zapisujemy plik i restartujemy Nginx poleceniem docker-compose restart. Wchodzimy na stronę Nextcloud (nextcloud.twoja-domena.pl), podajemy nową nazwę administratora i hasło. Przechodzimy dalej.

Podczas tego kroku napotkałem dziwny błąd. W moim przypadku przekierowanie nastąpiło do index.php?…, bez domeny. Dziwne, aczkolwiek rozwiązaniem okazało się dopisanie na początku nextcloud.twoja-domena.pl/ i kontynuowanie konfiguracji. Później problem już nie występował.

Nim przejdziesz do tworzenia użytkowników z poziomu panelu administratora i zmieniania innych konfiguracji pod siebie, pozostały do zrobienia dwie rzeczy. Po pierwsze, przejdź do Ustawienia->Ustawienia podstawowe i w sekcji Zadania w tle ustaw Cron. Następnie na serwerze wykonujemy polecenie crontab -e i dodajemy poniższą linię. Oczywiście, założyłem, że nazwa kontenera to nextcloud_nextcloud-app_1. Nazwy swoich kontenerów możesz sprawdzić komendą docker container ls.

*/5 * * * * docker exec -u www-data nextcloud_nextcloud-app_1 php cron.php

Zapisujemy plik i wychodzimy z edytora. Cron automatycznie odświeży swoją konfigurację. Zadanie to powinno wykonać się co każde pełne 5 minut (5 minut po pełnej godzinie, 10 minut po pełnej godzinie, i tak dalej). Można zweryfikować to najeżdżając na zieloną kropkę koło Zadania w tle w ustawieniach Nextcloud. Jest tam podany czas ostatniego wywołania. Drugą rzeczą jest edycja pliku /docker/nextcloud/html/config/config.php. Edytujemy (bądź dopisujemy jeśli nie istnieją) poniższe konfiguracje. Bez nich nie byłem w stanie połączyć aplikacji desktopowej Nextcloud z serwerem.

'overwrite.cli.url' => 'https://nextcloud.twoja-domena.pl',
'overwriteprotocol' => 'https',

Po edycji konfiguracji warto zrestartować Nextcloud poleceniem docker-compose restart.

Podsumowanie

Podsumowując, dzisiaj udało nam się roszerzyć nasz katalog usług o Giteę, Dokuwiki oraz Nextcloud. Moim zdaniem są to bardzo przydatne usługi, które na pewno w moim wypadku znajdą zastosowanie. A już w nastepnym odcinku zajmiemy się konfiguracją serwera poczty e-mail.

I na koniec jak zawsze – zapraszam do kontaktu! Do zobaczenia 😉