===================
== Verin's Pages ==
===================
Verin's Web Corner

Grocy Install

selfhosting

I used to be able to keep track of the family’s food stocks, but lately I haven’t been able to. My sibling found two (2) expired bags of tomato sauce in the small pantry and expired cheese in the fridge. How did I overlook that, and how do I avoid such things in the future? Since I was already dipping my toes into self-hosting, I looked for solutions in the awesome-selfhosting site and found Grocy.

My requirements:

  • Bare metal install in /var/www/grocy
  • Use a subdomain
  • Use Nginx as a reverse proxy

Simple enough, right? There are guides in the site but somehow the Nginx configs in the links weren’t working on my install. I don’t really know anything in-depth about self-hosting other than what configs I can copy online and following installation guides so I couldn’t hope to fix the error myself. I even looked through the closed issues and still I kept getting 504 errors. So I caved in and asked ChatGPT to help me write a better config file.

Keep in mind I am in no way an expert; always check the documentation before you try or Google other steps. Here is how I installed it.

My pre-requisites

I had the following installed in a Debian 11 server.

  • Nginx
  • PHP 8.2 version
  • Certbot

I also had a subdomain name for Grocy (grocy.domain.com in the examples).

I was not logged in as root; /var/www in my server is owned by root, so most of the commands below were prefaced with sudo.

Installation

  1. Logged in to server

  2. Updated any packages.

sudo apt update
sudo apt upgrade -y
  1. Installed required PHP packages.
    sudo apt install php8.2-mbstring php8.2-fileinfo php8.2-pdo_sqlite php8.2-gd php8.2-ctype php8.2-zlib php8.2-intl

(If these don’t work try php-mbstring and so on.)

  1. Installed SQLite.
    sudo apt install sqlite3

  2. Made a new directory for the subdomain and changed directory (cd).

sudo mkdir /var/www/grocy
cd /var/www/grocy
  1. Downloaded latest release and changed ownership (chown).
    Based on this (minimal Ubuntu installation)[https://github.com/grocy/grocy/issues/649]
sudo wget https://releases.grocy.info/latest
sudo unzip latest -d /var/www/grocy && rm latest
sudo chown -R www-data:www-data /var/www/grocy
  1. Customized configs (optional). Still based on the Github issue link above.
sudo cp /var/www/grocy/config-dist.php /var/www/grocy/data/config.php
sudo nano /var/www/grocy/data/config.php

I scrolled down and changed the CURRENCY to my country’s.

(Scroll through the file and change whatever needs changing, such as DEFAULT_LOCALE, ENERGY_UNIT, or other stuff. Leave the BASE_PATH stuff unchanged. A good rule of thumb is, if you are unsure, leave as is.)

  1. Created a config with Nginx as reverse proxy.
    sudo nano /etc/nginx/sites-available/Grocy

This opened up a blank file. I pasted the configs below BUT modified grocy.domain.com with my own subdomain.

server {
    listen 80;
    server_name grocy.domain.com;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl;
    server_name grocy.domain.com;

    # SSL certificate and key paths managed by Certbot
    ssl_certificate /etc/letsencrypt/live/grocy.domain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/grocy.domain.com/privkey.pem;

    # SSL configurations
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers off;
    ssl_ciphers 'TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384';

    # Enable HSTS (HTTP Strict Transport Security) to force HTTPS
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

    # Define the root directory for your Grocy installation
    root /var/www/grocy/public;

    # Adjust the following line to use index.php as the entry point
    index index.php;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php8.2-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }

    # Additional configuration for static files, if needed
    location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
        expires max;
        log_not_found off;
    }

    # Additional security headers, adjust as needed
    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-Content-Type-Options "nosniff";
    add_header X-XSS-Protection "1; mode=block";

    # Enable Gzip compression if desired
    gzip on;
    gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

    # Log settings, adjust as needed
    access_log /var/log/nginx/grocy_access.log;
    error_log /var/log/nginx/grocy_error.log;
}

If you inspect the files in /var/www/grocy with ls, you will see that there is no homepage file there – no index.php. It’s actually in the /var/www/grocy/public directory; hence, you will find that in the config file above as the root directory.

  1. Created Let’s Encrypt certificate. The eagle-eyed will notice I already included the SSL certificate location in the above config. I used Certbot here to get a free Let’s Encrypt certificate.

sudo certbot certonly --nginx -d grocy.domain.com

  1. Checked the Nginx config.
    sudo nginx -t
    No errors on my end.

  2. Made symlink to enable the site.
    sudo ln -s /etc/nginx/sites-available/grocy /etc/nginx/sites-enabled

  3. Restarted the services.

sudo systemctl restart nginx
sudo systemctl restart php8.2-fpm

And the site was finally live! I logged in with the default admin/admin username/pword combo, then immediately changed them both.

Actually it wasn’t that straightforward as I wrote above. I was dumb and forgot the required PHP packages and whenever I navigated to the Grocy subdomain it told me I was missing this and that package.

Well anyway after all that I got Grocy up and running. The next hurdle is actually getting the motivation to log all the things in my pantry. I don’t have any sort of home automation so the fancier stuff is out of reach; luckily I am poor and have few food stocks so logging them would be faster. I’ll need to set half a day to catalog.

Then the next is actually getting the family to use Grocy. I am thinking of installing a wall-mounted tablet in the kitchen so that they could easily check stocks and mark stuff as opened or consumed, but until then, I will have to refine the workflow, so to speak, and then ease my family into using the app.

It’s a rabbit hole, I can see now.