QNAP oraz InvoiceNinja = webowe fakturowanie za darmo na naszym serwerze

QNAP oraz InvoiceNinja = webowe fakturowanie za darmo na naszym serwerze

Jest wiele serwisów online gdzie możemy fakturować, jednak po co płacić za to skoro posiadamy QNAP oraz możemy samodzielnie taką aplikację uruchomić na naszym serwerze.
Wykorzystamy tutaj konteneryzację oraz aplikację Invoice Ninja która jest też w wersji polskiej – mowa o pakietach językowych.
Na początek utworzymy kontener LXC z systemem Debian, tutaj celowo idę w LXC, a nie dockera gdyż mamy większe pole do konfiguracji.
Prościej też będzie zainstalowac aplikację jak i dodatki typu certyfikat SSL dla naszej aplikacji.
Konfiguracja sieciowa będzie opierać się na wczesniej utworzonym wirtualnym switchu oraz sam kontener otrzyma sięc typu bridge, co ułatwi nam zarządzanie. Aplikacja w moim wypadku otrzyma adres IP z mojego routera
Na początek zatem tworzymy kontener z systemem Debian.


Pamietajmy aby uprzednio zrobić wirtualny przełącznik a sam kontener ustawić w bridge

Kolejnym etapem jest przejście do terminala oraz wykonanie upgrade debiana do wersji najnowszej -> https://www.8px.pl/aktualizacja-debian-8-jessie-do-debian-9-stretch-na-qnap/

Instalujemy dodatkowe pakiety:

apt-get install dialog tzdata locales anacron rsyslog vim mc logrotate openssh-server sudo postfix apt-transport-https lsb-release ca-certificates curl wget

Konfigurujemy czas oraz locale

dpkg-reconfigure locales
root@faktury:~# vim /etc/default/locale

dodajemy

LC_ALL=pl_PL.UTF-8

teraz musimy się przelogować

Ustawiamy polską strefę czasową

dpkg-reconfigure tzdata

wybieramy strefę czasową Europa/Warszawa

Current default time zone: 'Europe/Warsaw'
Local time is now:      Wed Apr 25 09:22:33 CEST 2018.
Universal Time is now:  Wed Apr 25 07:22:33 UTC 2018.

Ustawiamy łatwy dostęp do SSH dla konta root

root@faktury:~# cd /etc/ssh
root@faktury:/etc/ssh# vim sshd_config

zmieniamy:

# PermitRootLogin prohibit-password

na

PermitRootLogin yes

oraz restartujemy ssh i nadajemy hasło root

root@faktury:/etc/ssh# /etc/init.d/ssh restart
[ ok ] Restarting ssh (via systemctl): ssh.service.
root@faktury:/etc/ssh#
root@faktury:/etc/ssh# passwd
Enter new UNIX password:
Retype new UNIX password:
passwd: password updated successfully
root@faktury:/etc/ssh#

Po zalogowaniu się do SSH instalujemy wymagane komponenty, najnowszą wersję php, nginx oraz mariadb

Na początek php:

sudo wget -O /etc/apt/trusted.gpg.d/php.gpg https://packages.sury.org/php/apt.gpg
echo "deb https://packages.sury.org/php/ $(lsb_release -sc) main" | sudo tee /etc/apt/sources.list.d/php.list
sudo apt-get update
sudo apt-get install php7.2-fpm php7.2-mysql php-pear composer php7.2-curl php7.2-zip php7.2-mbstring php7.2-gd php7.2-gmp

Jako dodatek można dodać redis, który aplikacja wspiera

apt-get install php7.2-redis redis-server

Teraz instalacja serwera WWW, w tym wypadku mój ulubiony czyli nginx

apt-key adv --keyserver keyserver.ubuntu.com --recv-keys ABF5BD827BD9BF62
vim /etc/apt/sources.list

dodajemy repo oficjalne nginx:

deb http://nginx.org/packages/debian/ stretch nginx
deb-src http://nginx.org/packages/debian/ stretch nginx

oraz instalujemy pakiety

apt-get install nginx

Teraz czas na MariaDB jako baza mysql

sudo apt-get install software-properties-common dirmngr
apt-key adv --recv-keys --keyserver keyserver.ubuntu.com 0xF1656F24C74CD1D8
add-apt-repository 'deb [arch=amd64,i386,ppc64el] http://mariadb.kisiek.net/repo/10.2/debian stretch main'
apt-get update && apt-get install mariadb-server

Ustawiamy hasło root do bazy mysql

Czas konfigurację – tutaj będzie ona bardzo domyślna, jedyna modyfikacja to SSL/TLS oraz http2.

root@faktury:~# mkdir /etc/nginx/ssl
root@faktury:~# openssl dhparam -out /etc/nginx/ssl/dhparam.pem 2048
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/nginx/ssl/nginx.key -out /etc/nginx/ssl/nginx.crt
Generating a 2048 bit RSA private key
...............................................+++
.............................................................................+++
writing new private key to '/etc/nginx/ssl/nginx.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:PL
State or Province Name (full name) [Some-State]:Pomorskie
Locality Name (eg, city) []:Gdansk
Organization Name (eg, company) [Internet Widgits Pty Ltd]:8px
Organizational Unit Name (eg, section) []:IT
Common Name (e.g. server FQDN or YOUR name) []:192.168.1.108
Email Address []:admin@8px.pl
root@faktury:~# ls /etc/nginx/ssl/
dhparam.pem  nginx.crt	nginx.key

Tworzymy konfigurację:

vim /etc/nginx/conf.d/default.conf

Nie posługuję się domeną a adresem IP 192.168.1.108 – produkcyjnie ustawiamy swoje wartości

Podmieniamy zawartość na coś takiego:

server {
        listen 80;
        
        location / {
                return 301 https://192.168.1.108$request_uri;
        }
}
server {
        listen 443 ssl http2;

    	ssl_certificate /etc/nginx/ssl/nginx.crt;
		ssl_certificate_key /etc/nginx/ssl/nginx.key;

        root /var/www/faktury/public;

        index index.php index.html;


               location / {
                try_files $uri $uri/ /index.php$is_args$args;
        }

		fastcgi_buffers  16 16k;
		fastcgi_buffer_size  32k;

        location ~ \.php$ {
                fastcgi_index  index.php;
                fastcgi_split_path_info ^(.+\.php)(/.+)$;
                include       fastcgi_params;
                fastcgi_param PATH_INFO       $fastcgi_path_info;
                fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
        }
}

Tworzymy katalog gdzie będzie składowana nasza aplikacja

mkdir /var/www
mkdir /var/www/faktury

Można sprawdzić czy konfiguracja nginx jest poprawna

root@faktury:/etc/nginx/conf.d# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

I wykonujemy restart serwera aby załadował nową konfigurację

root@faktury:/etc/nginx/conf.d# /etc/init.d/nginx restart

Poprawiamy usera, którym php będzię się posługiwał. W przypadku instalacji z repo nginx jest to nginx. Jeżeli byśmy instalowali wszystko z repo debiana to będzie to www-data. Celowo instaluje z repo dodatkowych aby uzyskać najnowsze wersję oprogramowania

sed -i 's/www-data/nginx/g' /etc/php/7.2/fpm/pool.d/www.conf

Restart php-fpm

root@faktury:/etc/php/7.2/fpm/pool.d# /etc/init.d/php7.2-fpm restart
[ ok ] Restarting php7.2-fpm (via systemctl): php7.2-fpm.service.

Zakładamy bazę oraz usera:

root@faktury:/etc/php/7.2/fpm/pool.d# mysql -p
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 28
Server version: 10.2.14-MariaDB-10.2.14+maria~stretch-log mariadb.org binary distribution

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> drop database ninja;
Query OK, 0 rows affected (0.01 sec)

MariaDB [(none)]> CREATE SCHEMA `ninja` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
Query OK, 1 row affected (0.00 sec)

MariaDB [(none)]> CREATE USER 'ninja'@'localhost' IDENTIFIED BY 'ninja';
Query OK, 0 rows affected (0.00 sec)

MariaDB [(none)]> GRANT ALL PRIVILEGES ON `ninja`.* TO 'ninja'@'localhost';
Query OK, 0 rows affected (0.00 sec)

MariaDB [(none)]> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)

MariaDB [(none)]> \q

Teraz musimy pobrać aplikację – użyjemy git-a

cd /var/www/faktury && git clone https://github.com/invoiceninja/invoiceninja.git .
Cloning into 'invoiceninja'...
remote: Counting objects: 83643, done.
remote: Compressing objects: 100% (117/117), done.
remote: Total 83643 (delta 99), reused 137 (delta 68), pack-reused 83458
Receiving objects: 100% (83643/83643), 240.88 MiB | 14.31 MiB/s, done.
Resolving deltas: 100% (62809/62809), done.

Musimy zainstalować składniki wymagane przez aplikację

composer install

Teaz czekamy na instalację pakietów wymaganych przez naszą aplikację.

Nadajemy odpowiedniego właściciela do katalogu

chown -R nginx:nginx /var/www

Teraz można instalować aplikację.

Musimy podać adres jakim będziemy się posługiwać oraz dane do bazy SQL

Warto dodać konfigurację SMTP aby aplikacja mogła wysyłać maile

oraz konfiguracja pierwszego usera

Gotowe :)

Teraz tylko ustawiamy polską lokalizację, dane firmy i działamy.