diff --git a/.gitignore b/.gitignore index 7376571..3576efa 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ docker-compose.override.yml +.DS_Store diff --git a/README.md b/README.md index 52d3e47..ee9db1e 100644 --- a/README.md +++ b/README.md @@ -18,28 +18,28 @@ Warning: There are portions of the software that may not work. I don't warranty ## Setup +For Synology boxes, see [this setup guide instead](./SETUP-SYNOLOGY.md). + 1. You'll need Docker to run [RecipeSage](https://recipesage.com) locally. Although you _can_ attempt to run it without Docker, you're on your own. 2. Start all containers with `docker compose up -d` -3. On first run, and when updating, you'll need to run database migrations with `./migrate.sh` -4. The app should be available at port 80. You can change that by changing [this](https://github.com/julianpoy/RecipeSage-selfhost/blob/a1133c51af24ca78f9bc9537e147411b5e7e311a/docker-compose.yml#L8) to something else, such as `3000:80` for port 3000. +3. The app should be available at port 7270. You can change that by changing [this](https://github.com/julianpoy/RecipeSage-selfhost/blob/a1133c51af24ca78f9bc9537e147411b5e7e311a/docker-compose.yml#L8) to something else, such as `3000:80` for port 3000. -### Updating +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](https://caddyserver.com/docs/install) or [Nginx Proxy Manager](https://nginxproxymanager.com/guide) if you are unfamiliar with reverse proxies. A reverse proxy isn't strictly necessary to use RecipeSage self-hosted, however. -First, take a look at the changelog below for any special upgrade notes. Then follow the steps below. +### Updating -As with any migration/upgrade, I recommend taking a backup of your volumes before migrating to avoid any potential data loss. +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. -Update your local copy of this repo with the latest from this repository. If cloned with Git, this is as simple as `git pull`. +1. [_Take a look at the changelog below for any special upgrade notes_](#changelog). Then follow the steps below. -Update your local images: `docker compose pull`. +2. Update your local copy of this repo with the latest from this repository. If cloned with Git, this is as simple as `git pull`. -Then, down & up the containers: `docker compose down --remove-orphans && docker compose up -d` +3. Update your local images: `docker compose pull`. -Finally, run any pending migrations with `./migrate.sh` +4. Down & up the containers: `docker compose down --remove-orphans && docker compose up -d`
- ## Customization 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. @@ -68,11 +68,11 @@ It's fairly common that older CPUs (often shipped in prebuilt NASes) do not supp > Illegal Instruction (core dumped) -Since the ingredient-instruction-classifier container is not _required_ by RecipeSage, it can be removed/disabled from the docker-compose file if you don't have AVX instruction set support. Without the ingredient-instruction-classifier container, the automatic recipe import feature will still work on the majority of sites, but will be unable to pull content from sites that are particularly poorly formatted, or that have no metadata at all. +Since the ingredient-instruction-classifier container is not _required_ by RecipeSage, **it can be removed/disabled** from the docker-compose file if you don't have AVX instruction set support. Without the ingredient-instruction-classifier container, the automatic recipe import feature will still work on the majority of sites, but will be unable to pull content from sites that are particularly poorly formatted, or that have no metadata at all. #### I'm seeing an "unexpected error occurred" error when trying to register -This is most frequently because the migration script has not been run successfully. Note that if you change the name of the containers in the docker-compose file, the migration script will not be able to run the required migration script within the container, and you must do so by exec-ing into the container yourself, similar to what the script does. +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. #### Container Structure @@ -90,12 +90,22 @@ The `pushpin` container is a broker for all websocket connections. Without it, a 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 `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 _should still work_, but will be a bit less accurate or may not be able to pull ingredients or instructions from poorly formatted webpages. +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. ## Changelog +### v4.0.0 + +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: + +1. Update your local copy of the repository to v4.0.0 +2. Run `docker compose exec api tsx packages/backend/src/migrate` +3. If the command prior ran successfully, run `docker compose exec api npx prisma migrate resolve --applied 0_init` + ### v3.1.0 `docker-compose` has been officially deprecated, so the app has migrated to using `docker compose`. diff --git a/SETUP-SYNOLOGY.md b/SETUP-SYNOLOGY.md new file mode 100644 index 0000000..3bc53e5 --- /dev/null +++ b/SETUP-SYNOLOGY.md @@ -0,0 +1,93 @@ +# Synology Setup Guide + +These steps are specific to setting up RecipeSage on a Synology box. Please follow the normal setup instructions for non-Synology based installs. + +## Prerequisites + +- Version 7.2 of DSM running on your Synology NAS. +- The package `Container Manager` installed via the `Package Center` application on your Synology NAS. + +## Step 1 + +Copy the RecipeSage docker-compose.yml file [from here](https://raw.githubusercontent.com/julianpoy/RecipeSage-selfhost/main/docker-compose.yml). + +## Step 2 + +Open your Synology WebUI, and navigate to the `Container Manager` application via the applications menu. + + + +## Step 3 + +Switch to the project tab in the left sidebar of the `Container Manager`. + +Create a project either using the "create" button, and enter the corresponding details (as shown below) into the create project dialogue. + + + +**Note** that you'll paste in the docker-compose.yml file that you copied above into this dialogue. + +Click next. + +## Step 4 + +On the next page, you'll be presented with a dialogue asking if you want to provide web services to the created containers. You'll want to enable HTTP on port 7270 to the proxy container as shown below. + + + +Click next. + +## Step 5 + +On the next page, you'll be shown a summary of what you've configured. It should match the image below. + + + +If all looks correct, you can click done. + +## Step 6 + +At this point you may see a few modals pop up. One should be showing you the download & extracting progress for all of the RecipeSage containers. You'll also see a prompt like below regarding the web service configuration. + + + +Leave all of the settings default, but fill in the hostname field with the domain name you'd like to use for RecipeSage if you have one, such as (recipesage.yourdomain.com). If not, and you're just planning to use RecipeSage within your local network, just enter `recipesage` into this field and click the create button. + +## Step 7 + +Once the download & extracting progress window has completed, you should see text in that window similar to the following. + + + +You can press the done button. + +## Step 8 + +Navigate to http://YOUR_SYNOLOGY_IP_ADDRESS:7270 in your web browser, and you should see the RecipeSage interface! + +## Further Steps + +These steps are very well documented across the internet, and I recommend Googling for help here if you are unfamiliar with these concepts. Please do not open issues related to the following steps. + +If you entered a domain name for RecipeSage in step 6, you'll want to: + +- Follow [Synology's guide for getting an HTTPS certificate](https://kb.synology.com/en-my/DSM/tutorial/How_to_enable_HTTPS_and_create_a_certificate_signing_request_on_your_Synology_NAS) if you don't have a certificate for this domain name already configured. You can manage certificates and their assignments within `Control Panel -> Security -> Certificate`. +- Port forward port 80 & 443 via your router to your Synology box. (Google the model of your router for instructions for how to do this) +- Follow [Synology's guide for setting up DDNS for your domain](https://kb.synology.com/en-us/DSM/help/DSM/AdminCenter/connection_ddns?version=7) + +If you've followed all of the steps above, you should be able to access RecipeSage via the domain you configured. + +## Updating + +First, check any notes regarding the new version you'll be updating to [here](https://github.com/julianpoy/recipesage-selfhost#changelog) since there may be additional steps required. + +To update your copy of RecipeSage on your Synology NAS, first stop RecipeSage via the `Container Manager -> Project` interface. + +After all of the associated RecipeSage containers stop, navigate to the `YAML Configurations` tab within the RecipeSage project you set up. + +Copy the latest docker-compose.yaml from here [from here](https://raw.githubusercontent.com/julianpoy/RecipeSage-selfhost/main/docker-compose.yml), and replace the content of the `YAML Configurations` window with the content of the new docker-compose.yml file. + +Click Save and select `Build and start the project (rebuild the image)`. + +RecipeSage should be updated. Again, please perform any additional steps described [here](https://github.com/julianpoy/recipesage-selfhost#changelog) if required. + diff --git a/docker-compose.yml b/docker-compose.yml index 81c4ab1..cb392c4 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,12 +1,12 @@ -version: '3.7' +# This config file is for RecipeSage-selfhost version 4.0.0, and RecipeSage version 2.13.1. + +version: '3.7' # (this is the docker compose version, not RecipeSage version) services: proxy: # The proxy must not be removed. If needed, point your own proxy to this container, rather than removing this container_name: recipesage_proxy - image: nginx - volumes: - - ./proxy.conf:/etc/nginx/conf.d/default.conf + image: julianpoy/recipesage-selfhost-proxy:v4.0.0 ports: - - 80:80 + - 7270:80 depends_on: - static - api @@ -14,17 +14,19 @@ services: restart: unless-stopped static: # Hosts frontend assets container_name: recipesage_static - image: julianpoy/recipesage-selfhost:static-v2.12.10 + image: julianpoy/recipesage-selfhost:static-v2.13.1 restart: unless-stopped api: # Hosts backend API container_name: recipesage_api - image: julianpoy/recipesage-selfhost:api-v2.12.10 + image: julianpoy/recipesage-selfhost:api-v2.13.1 depends_on: - postgres - typesense - pushpin - browserless - command: npx ts-node --swc --project packages/backend/tsconfig.json packages/backend/src/bin/www + # Swap commands if you want to disable automatic migrations on startup + command: sh -c "npx prisma migrate deploy && npx ts-node --swc --project packages/backend/tsconfig.json packages/backend/src/bin/www" + # command: npx ts-node --swc --project packages/backend/tsconfig.json packages/backend/src/bin/www environment: - STORAGE_TYPE=filesystem - FILESYSTEM_STORAGE_PATH=/rs-media @@ -54,11 +56,11 @@ services: volumes: - apimedia:/rs-media restart: unless-stopped - typesense: + typesense: # Provides the fuzzy search engine container_name: recipesage_typesense image: typesense/typesense:0.24.1 volumes: - - typesensedata:/data + typesensedata:/data command: "--data-dir /data --api-key=recipesage_selfhost --enable-cors" restart: unless-stopped pushpin: # Provides websocket support @@ -81,22 +83,26 @@ services: - POSTGRES_USER=recipesage_selfhost - POSTGRES_PASSWORD=recipesage_selfhost volumes: - - postgresdata:/var/lib/postgresql/data + postgresdata:/var/lib/postgresql/data restart: unless-stopped browserless: # A headless browser for scraping websites with the auto import tool container_name: recipesage_browserless - image: browserless/chrome:1.57-puppeteer-19.2.2 + image: browserless/chrome:1.61.0-puppeteer-21.4.1 environment: - MAX_CONCURRENT_SESSIONS=3 - MAX_QUEUE_LENGTH=10 restart: unless-stopped - ingredient-instruction-classifier: # A mini server that runs a machine learning model able to classify text for improved automatic import - container_name: recipesage_classifier - image: julianpoy/ingredient-instruction-classifier:1.4.9 - environment: - - SENTENCE_EMBEDDING_BATCH_SIZE=200 - - PREDICTION_CONCURRENCY=4 - restart: unless-stopped + + # Uncomment the lines below to enable the ingredient instruction classifier. It's somewhat resource intensive and requires AVX instruction support on your CPU, but does improve site compatibility for the automatic import tool. + + # ingredient-instruction-classifier: # A mini server that runs a machine learning model able to classify text for improved automatic import site support. Not required for application to run, and will crash if your CPU does not support AVX instructions + # container_name: recipesage_classifier + # image: julianpoy/ingredient-instruction-classifier:1.4.11 + # environment: + # - SENTENCE_EMBEDDING_BATCH_SIZE=200 + # - PREDICTION_CONCURRENCY=2 + # restart: unless-stopped + volumes: apimedia: driver: local diff --git a/migrate.sh b/migrate.sh deleted file mode 100755 index 92b6072..0000000 --- a/migrate.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh - -echo "Performing migrations. This could take up to 1 minute." - -docker compose exec api tsx packages/backend/src/migrate - -echo "Migrations complete." - diff --git a/src/img/synology-container-manager.png b/src/img/synology-container-manager.png new file mode 100644 index 0000000..13453a0 Binary files /dev/null and b/src/img/synology-container-manager.png differ diff --git a/src/img/synology-new-project-done.png b/src/img/synology-new-project-done.png new file mode 100644 index 0000000..25dd4de Binary files /dev/null and b/src/img/synology-new-project-done.png differ diff --git a/src/img/synology-new-project-summary.png b/src/img/synology-new-project-summary.png new file mode 100644 index 0000000..3e3c76d Binary files /dev/null and b/src/img/synology-new-project-summary.png differ diff --git a/src/img/synology-new-project-web-portal-settings.png b/src/img/synology-new-project-web-portal-settings.png new file mode 100644 index 0000000..aa37ba5 Binary files /dev/null and b/src/img/synology-new-project-web-portal-settings.png differ diff --git a/src/img/synology-new-project-web-service-setup.png b/src/img/synology-new-project-web-service-setup.png new file mode 100644 index 0000000..f2cce93 Binary files /dev/null and b/src/img/synology-new-project-web-service-setup.png differ diff --git a/src/img/synology-new-project.png b/src/img/synology-new-project.png new file mode 100644 index 0000000..d9073be Binary files /dev/null and b/src/img/synology-new-project.png differ diff --git a/src/proxy/Dockerfile b/src/proxy/Dockerfile new file mode 100644 index 0000000..76baf52 --- /dev/null +++ b/src/proxy/Dockerfile @@ -0,0 +1,6 @@ +FROM nginx + +COPY ./proxy.conf /etc/nginx/conf.d/default.conf + +EXPOSE 80 + diff --git a/proxy.conf b/src/proxy/proxy.conf similarity index 100% rename from proxy.conf rename to src/proxy/proxy.conf