Introduction
My gf asked for a way to have a shared grocery list that we can both access for when we go running errands or go to the supermarket, since I have a homelab and all. So like any good boyfriend I got to work to fulfill her request. After some searching I came across Specifically Clementines, a self-hosted open source grocery list (formerly named groceries).
Installation - Docker
I planned to host this on an OpenSUSE VM I am already running to Automatically generate IG reels. The whole thing will be running in Docker anyway. I followed the Docker Compose setup from the documentation, which was a bit daunting at first (mainly because my docker-compose experience so far has been pretty plug-and play with things like Immich and TriliumNext), but all the info is there if you just read carefully.
I mainly built off the simple example docker-simple.tar.gz, changing the docker-compose values I
needed to. The things I ended up changing in the docker-compose.yaml file:
...
DEFAULT_API_URL: https://my_groceries_url/api
...
COUCHDB_URL: https://my_couchdb_url
...
COUCHDB_ADMIN_USER: new username
COUCHDB_ADMIN_PASSWORD: new password
...
GROCERY_URL: https://my_groceries_url
GROCERY_API_URL: https://my_groceries_url/api
...
In the end I didn't need to change that much, but I did for a moment get stuck on the couchdb parameters, as I first had set my couchdb url to the same url as the api url, but these need to be two different urls. I ended up registering 2 DNS A-records for my domain, one for the api and one for the couchdb database.
Installation - Nginx
Because I want to be able to access this from anywhere in the world, I want to put it behind my Nginx reverse proxy to make it more secure. I had to create 2 new sites, one for the API and one for the couchdb database. The site for the API looks like this:
server {
server_name my_groceries_url;
# route API requests to the backend server of specifically-clementines
location /api/ {
rewrite ^/api(/.*)$ $1 break;
proxy_pass http://ip-of-vm:3333;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port 443;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Real-IP $remote_addr;
client_max_body_size 20M;
}
# route all other requests to the frontend
location / {
proxy_pass http://ip-of-vm:8100;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port 443;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Real-IP $remote_addr;
client_max_body_size 20M;
}
}
And the site for the database looks like this:
server {
server_name my_couchdb_url;
location / {
proxy_pass http://ip-of-vm:5984;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port 443;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Real-IP $remote_addr;
client_max_body_size 20M;
}
}
For HTTPS, I of course used certbot.
Removing the system categories and items
After setting everything up, there was one thing I didn't like: the system categories and items. These were in English, and I want to add my items and categories in dutch. They were also items and categories I won't really use, like 1% and 2% milk. You can't remove these from the web ui or the Android app, so I had to delete them from the database by logging into the couchdb front-end, and selected them using this mongo query:
{
"selector": {
"type": "category"
}
}
and this one:
{
"selector": {
"defaultCategoryID": { "$exists": true }
},
}
After removing them from the database, I had to reinstall the Android app to have the changes replicated in the app.
UPDATE 25-05-2025: I moved this to an LXC container that runs all my docker containers some time ago, and today I moved all those to a separate VM