RecipeSage is a free personal recipe keeper, meal planner, and shopping list organizer for Web, IOS, and Android. It can be used to share recipes, shopping lists, and meal plans with your family & friends, as well as import (grab) recipes from any URL on the web.
This repository contains the configuration needed to run your own, personal instance of RecipeSage.
The docker images used here are based on the same version that the official RecipeSage uses in the cloud for the hosted instance. I'm mostly focused on the official hosted instance, but please let me know if there are issues when attempting to run it locally!
Please note that this repository and all public RecipeSage branding, docker images, code, binaries, and everything else are for personal, private (non-public), non commercial use only. All RecipeSage branding is not licensed for reuse.
Warning: There are portions of the software that may not work. I don't warranty the functionality here. You're in charge of making backups and making sure you don't lose data, especially when updating!
For Synology boxes, see this setup guide instead.
- You'll need Docker to run RecipeSage locally. Although you can attempt to run it without Docker, you're on your own.
- Start all containers with
docker compose up -d
- The app should be available at port 7270. You can change that by changing this to something else, such as
3000:80
for port 3000.
You'll very likely want to put RecipeSage behind a reverse proxy for SSL termination (and so that you can run more than just RecipeSage!). That's not covered by this README, but I encourage you look at Caddy or Nginx Proxy Manager if you are unfamiliar with reverse proxies. A reverse proxy isn't strictly necessary to use RecipeSage self-hosted, however.
By default, the database will be automatically migrated when updating to a new container version. As with any migration/upgrade, I strongly recommend taking a backup of your volumes before migrating to avoid any potential data loss. My first recommendation when encountering issues after an update will be to rollback, which will be impossible if you don't have a backup.
-
Take a look at the changelog below for any special upgrade notes. Then follow the steps below.
-
Update your local copy of this repo with the latest from this repository. If cloned with Git, this is as simple as
git pull
. -
Update your local images:
docker compose pull
. -
Down & up the containers:
docker compose down --remove-orphans && docker compose up -d
The following sections provide some information on customizing your instance. Following the "setup" section is enough to get you running with a RecipeSage instance like that of the official site.
If you want to disable registration, after you have registered yourself as a user, add this to the top of the docker environment variables:
DISABLE_REGISTRATION=true
Then, down & up the containers: docker compose down && docker compose up -d
When registration is disabled, the registration screen will still appear but will fail with an error if anyone tries to register.
The "bonus features" from the hosted version can be activated by running the following command (swap out the email address with your account email). Please contribute to the development & maintenance of RecipeSage at https://recipesage.com/#/contribute -- Julian.
./activate.sh example@example.com
This section is optional, but does enable some features
Some of the features within the app rely on an OpenAI API key and will not be functional by default. This includes the "scan from image", "scan from PDF", and "autofill from text" features.
I cannot provide support for setting up an OpenAI account.
- Create an API key with OpenAI at https://platform.openai.com and setup your credit card with them
- Set
OPENAI_API_KEY
in your docker-compose to the API key you created (it's already in there, just with no value) - Re-create the containers via docker-compose if you've already started them
This is most frequently because the migration script has not been run successfully. Please include logs from the API container when posting any issue related to this.
This section is here just to explain the purpose of each container and why it's necessary. Following Docker principles, every part of the application is compartmentalized into it's own container with it's own singular responsibility. I've described what role each plays in making the application do what it does.
The proxy
container facilitates divvying up requests between the api
, the static
(frontend, and the minio
container. Without it, you'd need to route requests yourself, such as properly directing requests that head to /api/*
to the api
container, and requests that go to any other path on /*
to the static
container.
The static
container is a very simple image with the prebuilt frontend assets for that version of RecipeSage. The application cannot run without it.
The api
container facilitates all data storage for the application. The application cannot run without it.
The elasticsearch
container facilitates the hyper-accurate fuzzysearch for the app. Without it, search within the app will not work.
The pushpin
container is a broker for all websocket connections. Without it, all realtime interactions between multiple users won't work and will require a reload to get new content, such as when a shopping list item is checked off.
The postgres
container is the database. The application cannot run without it.
The browserless
container is a virtual web browser that is used to scrape recipe data when you paste a URL into the "autofill" feature of the app. Without it the recipe scraper should still work, but will fall back to JSDOM which will be significantly less accurate and may contain formatting errors.
The ingredient-instruction-classifier
container facilitates machine learning classification of ingredients and instructions, which is used to improve accuracy during the "autofill" feature. Without it the recipe scraper will still work, but will lose the ability to pull ingredients or instructions from webpates with no JSON-LD headers and no formatting.
Migrations are now automated, and use a different migration tool.
If you have an older version of this repository, you must upgrade to this version of the repository and do the following before upgrading to newer versions so that migrations all line up:
- Update your local copy of the repository to v4.0.0
- Run
docker compose exec api tsx packages/backend/src/migrate
- If the command prior ran successfully, run
docker compose exec api npx prisma migrate resolve --applied 0_init
- Restart the API container with
docker compose restart api
docker-compose
has been officially deprecated, so the app has migrated to using docker compose
.
Full ARM64 support is now official. All containters have associated ARM64 platform builds.
ElasticSearch has been removed in favor of TypeSense. You can remove any old ElasticSearch related containers or volumes if you choose (though the application still remains fully compatible with ElasticSearch, should you keep SEARCH_PROVIDER
as elasticsearch as well as ElasticSearch related environment variables the same).
No data will be lost if you choose to switch to TypeSense. TypeSense will be populated on your first login to the app after upgrading. TypeSense is faster for RecipeSage purposes, as well as less memory-intensive.
Revamp selfhosting configs. Use local filesystem rather than minio.
Important upgrade notes: (none of this applies to new users, only those with existing data)
The new docker compose.yml no longer uses minio, and instead writes directly to the local filesystem. You'll need to keep your minio instance from the old Dockerfile along with it's volume definition.
Update RecipeSage image to v2.9.0, ElasticSearch image to v8.4.3, and Browserless to 1.53.0.
Upgrade note: You must first upgrade your elasticsearch container image to v7.17 before upgrading to this new version.
Fix public access permissions for new minio installations.
Move minio behind app proxy.
Note: If you're upgrading from an earlier version of these selfhost configs, you'll need to make sure to continue to expose 9000 on the Minio container in order to maintain access to images uploaded before this change, or update the image path in the DB.
Initial release.