Grocy Install
selfhostingI 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
-
Logged in to server
-
Updated any packages.
sudo apt update
sudo apt upgrade -y
- 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.)
-
Installed SQLite.
sudo apt install sqlite3
-
Made a new directory for the subdomain and changed directory (
cd
).
sudo mkdir /var/www/grocy
cd /var/www/grocy
- 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
- 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.)
- 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.
- 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
-
Checked the Nginx config.
sudo nginx -t
No errors on my end. -
Made symlink to enable the site.
sudo ln -s /etc/nginx/sites-available/grocy /etc/nginx/sites-enabled
-
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.