This guide walks you through setting up your application on Ubuntu 22.04. You’ll install the required dependencies, configure the database, set up Nginx with SSL, and complete the final installation steps.
Be sure to replace invoicing.example.com
with your actual domain name, and update PASSWORD
with your own secure password.
Step 1: Update System Packages
Start by updating the system’s package list and upgrading existing packages
sudo apt update
sudo apt dist-upgrade -y
Step 2: Install Required PHP Packages
Next, install the necessary PHP packages for your application:
sudo apt install php8.3-bcmath php8.3-gmp php8.3-common \
php8.3-gd php8.3-mbstring php8.3-pdo php8.3-xml php8.3-cli \
php8.3-curl php8.3-zip php8.3-mysql php8.3-fpm
Step 3: Install and Configure MariaDB
Install MariaDB, which will be used for the database:
sudo apt install mariadb-server mariadb-client nginx
sudo systemctl enable --now mariadb
Run the MySQL secure installation:
sudo mysql_secure_installation
Enter current password for root (enter for none):
Switch to unix_socket authentication [Y/n] n
Change the root password [Y/n] y
Remove anonymous users? [Y/n] y
Disallow root login remotely? [Y/n] y
Remove test database and access to it? [Y/n] y
Reload privilege tables now? [Y/n] y
Step 4: Create Database and User
Access MariaDB to create your database and user:
sudo mysql -u root -p
Inside the MySQL prompt:
CREATE DATABASE invoicedb;
CREATE USER 'ninja'@'localhost' IDENTIFIED BY 'PASSWORD';
GRANT ALL PRIVILEGES ON invoicedb.* TO 'ninja'@'localhost';
FLUSH PRIVILEGES;
EXIT;
Step 5: Install Certbot for SSL
Install Certbot to enable SSL on Nginx:
sudo apt update
sudo apt install certbot
sudo apt install python3-certbot-nginx
Stop Nginx temporarily for SSL configuration:
sudo systemctl stop nginx
Now, use Certbot to obtain and install the SSL certificate:
sudo certbot --nginx --agree-tos --redirect --hsts --staple-ocsp --email [email protected] -d invoicing.example.com
Start Nginx again:
sudo systemctl start nginx
Step 6: Configure Nginx
Remove the default configuration and create a new one for your app:
sudo rm /etc/nginx/sites-enabled/default
sudo nano /etc/nginx/sites-available/invoiceninja
Add the following configuration:
server {
listen 443 ssl http2 default_server;
listen [::]:443 ssl http2 default_server;
server_name "invoicing.example.com";
client_max_body_size 20M;
if ($host != $server_name) {
return 301 https://$server_name$request_uri;
}
root /usr/share/nginx/invoiceninja/public;
gzip on;
gzip_types application/javascript application/x-javascript text/javascript text/plain application/xml application/json;
gzip_proxied no-cache no-store private expired auth;
gzip_min_length 1000;
index index.php index.html index.htm;
ssl_certificate "/etc/letsencrypt/live/invoicing.example.com/fullchain.pem";
ssl_certificate_key "/etc/letsencrypt/live/invoicing.example.com/privkey.pem";
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 10m;
ssl_ciphers 'AES128+EECDH:AES128+EDH:!aNULL';
ssl_prefer_server_ciphers on;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
charset utf-8;
include /etc/nginx/default.d/*.conf;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
if (!-e $request_filename) {
rewrite ^(.+)$ /index.php?q= last;
}
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_intercept_errors off;
fastcgi_buffer_size 16k;
fastcgi_buffers 4 16k;
}
location ~ /\.ht {
deny all;
}
location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt { access_log off; log_not_found off; }
access_log /var/log/nginx/ininja.access.log;
error_log /var/log/nginx/ininja.error.log;
sendfile off;
}
server {
listen 80;
server_name "invoicing.example.com";
add_header Strict-Transport-Security max-age=2592000;
rewrite ^ https://$server_name$request_uri? permanent;
}
Link this configuration to enable it:
sudo ln -s /etc/nginx/sites-available/invoiceninja /etc/nginx/sites-enabled/invoiceninja
Test the Nginx configuration:
sudo nginx -t
Step 7: Disable Apache and Enable Nginx
Disable Apache and make sure Nginx is enabled:
sudo systemctl stop apache2
sudo systemctl disable apache2
sudo systemctl enable nginx
sudo systemctl start nginx
Extra: Automatically Renew SSL Certificate
To make sure your Let’s Encrypt SSL certificate stays up to date, add a cron job that runs every day at 11:00 PM.
Open the root crontab:
sudo crontab -e
Then add this line at the bottom:
0 23 * * * certbot renew --quiet --deploy-hook "systemctl reload nginx"
Step 8: Install the Application
Navigate to the directory where you want to install the application and download it
cd /usr/share/nginx
sudo mkdir invoiceninja && cd invoiceninja
sudo wget https://github.com/invoiceninja/invoiceninja/releases/download/v5.11.68/invoiceninja.tar
sudo tar -xvf invoiceninja.tar
sudo rm invoiceninja.tar
Copy the example environment file:
sudo cp .env.example .env
sudo nano .env
Update key values
APP_URL=https://invoicing.example.com
DB_HOST=localhost
DB_DATABASE=invoicedb
DB_USERNAME=ninja
DB_PASSWORD=PASSWORD
Step 9: Set Permissions
Set the proper permissions for the application:
sudo chown -R www-data:www-data /usr/share/nginx/invoiceninja
Step 10: Set Up Cron Jobs
Set up a cron job for scheduled tasks:
sudo -u www-data crontab -e
Add the following line:
* * * * * php8.3 /usr/share/nginx/invoiceninja/artisan schedule:run >> /dev/null 2>&1
Step 11: Increase PHP Memory Limit
Edit the PHP configuration to increase the memory limit:
sudo nano /etc/php/8.3/fpm/php.ini
Search for memory_limit
and set it to 1024M
:
memory_limit = 1024M
Step 12: Reboot and Final Setup in Browser
Before proceeding with the final setup, it’s a good idea to reboot your server.
sudo reboot
After the reboot, open your browser and go to:
https://invoicing.example.com/setup
(Replace invoicing.example.com
with your actual domain name.)
On the setup page, fill in the following:
- App URL –
https://invoicing.example.com
- Database host – usually
localhost
- Database name –
invoicedb
- Database username –
ninja
- Database password –
PASSWORD
Then complete the rest of the setup as instructed on-screen