Commit 2913de9f78
Unsigned
Layout: unified · split
content/blog/2025-01-23-self-hosting-tandoor.org added +144
| @@ -0,0 +1,144 @@ | ||
| 1 | #+date: <2025-01-23 Thu 20:44:45> | |
| 2 | #+title: Self-Hosting Tandoor Recipe Manager | |
| 3 | #+description: Learn how to self-host Tandoor, the smart recipe management web app. | |
| 4 | #+filetags: :self-hosting: | |
| 5 | #+slug: self-hosting-tandoor | |
| 6 | ||
| 7 | * Overview | |
| 8 | ||
| 9 | [[https://tandoor.dev/][Tandoor]] is a smart recipe manager web application that allows you to: | |
| 10 | - Store your recipes | |
| 11 | - Search for recipes and ingredients | |
| 12 | - Share recipes with a link and permission system | |
| 13 | - Put recipes and ingredients into a shopping list | |
| 14 | - Plan your meals with a built-in calendar | |
| 15 | - Calculate nutritional values | |
| 16 | - Import recipes from websites and apps | |
| 17 | - Load existing recipes | |
| 18 | ||
| 19 | * Installation | |
| 20 | ||
| 21 | [[https://docs.tandoor.dev/][The Tandoor docs]] contain all of the relevant information needed to get start | |
| 22 | with the self-hosting process. | |
| 23 | ||
| 24 | This tutorial will use Docker Compose and Nginx on Ubuntu 24.04.1. | |
| 25 | ||
| 26 | ** Docker Compose | |
| 27 | ||
| 28 | On your machine, create a directory for Tandoor and copy down the =.env= and | |
| 29 | =docker-compose.yml= templates: | |
| 30 | ||
| 31 | #+begin_src shell | |
| 32 | mkdir ~/tandoor cd ~/tandoor wget | |
| 33 | https://raw.githubusercontent.com/vabene1111/recipes/develop/.env.template -O .env wget | |
| 34 | # Plain version of docker-compose.yml | |
| 35 | https://raw.githubusercontent.com/vabene1111/recipes/develop/docs/install/docker/plain/docker-compose.yml | |
| 36 | #+end_src | |
| 37 | ||
| 38 | Within these files, customize as needed. | |
| 39 | 1. =.env= | |
| 40 | a. Add a =SECRET_KEY= | |
| 41 | b. Define the =ALLOWED_HOSTS= | |
| 42 | c. Set the =POSTGRES_PASSWORD= | |
| 43 | 2. =docker-compose.yml= | |
| 44 | a. Update the =ports= since Nginx on my host is already using port 80 (e.g. | |
| 45 | =8087:80=) | |
| 46 | ||
| 47 | Once you've updated and saved the files, you can launch the container. | |
| 48 | ||
| 49 | #+begin_src shell | |
| 50 | sudo docker compose up -d | |
| 51 | #+end_src | |
| 52 | ||
| 53 | The application is now available at =localhost:8087= or =ip_address:8087= if | |
| 54 | accessing via a different machine. If accessing via a different machine, | |
| 55 | remember to allow port 8087 through any existing firewalls. | |
| 56 | ||
| 57 | ** Nginx Reverse Proxy | |
| 58 | ||
| 59 | Now that Tandoor is available locally, let's connect it to the Nginx web server | |
| 60 | running on the host machine. | |
| 61 | ||
| 62 | > Note: I use Nginx configuration files within the =conf.d= directory, but you | |
| 63 | > may need to use the =sites-available= directory, depending on your | |
| 64 | > installation of Nginx. | |
| 65 | ||
| 66 | #+begin_src shell | |
| 67 | cd /etc/nginx/conf.d/ | |
| 68 | sudo nano recipes.conf | |
| 69 | #+end_src | |
| 70 | ||
| 71 | Within this file, define your website configuration. The example below is my | |
| 72 | default configuration and utilizes a wildcard certificate for =*.example.com= | |
| 73 | that covers all of my subdomains. If you don't have a wildcard certificate, you | |
| 74 | will need to generate an SSL certificate for your domain. | |
| 75 | ||
| 76 | #+begin_src config | |
| 77 | server { | |
| 78 | listen 443 ssl; | |
| 79 | listen [::]:443 ssl; | |
| 80 | http2 on; | |
| 81 | server_name recipes.example.com; | |
| 82 | ||
| 83 | # SSL | |
| 84 | ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; | |
| 85 | ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; | |
| 86 | ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem; | |
| 87 | ||
| 88 | # reverse proxy | |
| 89 | location / { | |
| 90 | proxy_pass http://localhost:8087/; | |
| 91 | proxy_set_header Host $http_host; | |
| 92 | proxy_set_header X-Forwarded-Proto $scheme; | |
| 93 | proxy_redirect http://127.0.0.1:8080 https://recipes.example.com; | |
| 94 | } | |
| 95 | ||
| 96 | location /media/ { | |
| 97 | root /media/; | |
| 98 | index index.html index.htm; | |
| 99 | } | |
| 100 | } | |
| 101 | ||
| 102 | # HTTP redirect | |
| 103 | server { | |
| 104 | listen 80; | |
| 105 | listen [::]:80; | |
| 106 | server_name recipes.example.com; | |
| 107 | include custom.d/letsencrypt.conf; | |
| 108 | ||
| 109 | if ($host ~ ^[^.]+\.example\.com$) { | |
| 110 | return 301 https://$host$request_uri; | |
| 111 | } | |
| 112 | } | |
| 113 | #+end_src | |
| 114 | ||
| 115 | Save and close the configuration file and then restart the web server. | |
| 116 | ||
| 117 | #+begin_src shell | |
| 118 | sudo systemctl restart nginx.service | |
| 119 | #+end_src | |
| 120 | ||
| 121 | The app is now available on your custom domain! | |
| 122 | ||
| 123 | ** Screenshots | |
| 124 | ||
| 125 | #+caption: Login | |
| 126 | [[https://img.cleberg.net/blog/20250123-self-hosting-tandoor/login.png]] | |
| 127 | ||
| 128 | #+caption: Recipes | |
| 129 | [[https://img.cleberg.net/blog/20250123-self-hosting-tandoor/recipes.png]] | |
| 130 | ||
| 131 | #+caption: Meal Plan | |
| 132 | [[https://img.cleberg.net/blog/20250123-self-hosting-tandoor/mealplan.png]] | |
| 133 | ||
| 134 | #+caption: Shopping Lists | |
| 135 | [[https://img.cleberg.net/blog/20250123-self-hosting-tandoor/shopping.png]] | |
| 136 | ||
| 137 | #+caption: Cook Book | |
| 138 | [[https://img.cleberg.net/blog/20250123-self-hosting-tandoor/cookbook.png]] | |
| 139 | ||
| 140 | #+caption: Import | |
| 141 | [[https://img.cleberg.net/blog/20250123-self-hosting-tandoor/import.png]] | |
| 142 | ||
| 143 | #+caption: Administration Panel | |
| 144 | [[https://img.cleberg.net/blog/20250123-self-hosting-tandoor/admin.png]] | |
theme/templates/index.html +7 −6
| @@ -8,6 +8,13 @@ uid [ultimate] Christian Cleberg <hello@cleberg.net></pre> | ||
| 8 | 8 | <section> |
| 9 | 9 | <h2>Recent Blog Posts</h2> |
| 10 | 10 | |
| 11 | <div class="post"> | |
| 12 | <time datetime="2025-01-23 20:44:45">2025-01-23</time> | |
| 13 | <a href="/blog/self-hosting-tandoor.html" | |
| 14 | >Self-Hosting Tandoor Recipe Manager</a | |
| 15 | > | |
| 16 | </div> | |
| 17 | ||
| 11 | 18 | <div class="post"> |
| 12 | 19 | <time datetime="2024-12-29 17:45:00">2024-12-29</time> |
| 13 | 20 | <a href="/blog/self-hosting-the-lounge.html" |
| @@ -21,12 +28,6 @@ uid [ultimate] Christian Cleberg <hello@cleberg.net></pre> | ||
| 21 | 28 | >Using Ollama As a Code Assistant in VS Codium</a |
| 22 | 29 | > |
| 23 | 30 | </div> |
| 24 | <div class="post"> | |
| 25 | <time datetime="2024-09-23 19:52:20">2024-09-23</time> | |
| 26 | <a href="/blog/self-hosting-transmission.html" | |
| 27 | >Self-Hosting Transmission Bittorrent Client</a | |
| 28 | > | |
| 29 | </div> | |
| 30 | 31 | |
| 31 | 32 | <br /> |
| 32 | 33 | <a href="/blog/">All Posts →</a> |