Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@ ScaleTail provides ready-to-run [Docker Compose](https://docs.docker.com/compose

| 🥘 Service | 📝 Description | 🔗 Link |
| --------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- |
| 🥘 **Kitchenowl** | A self-hosted smart grocery list and recipe manager with features like expense tracking, weekly meal planner, rich recipe import options and OIDC support. | [Details](services/kitchenowl) |
| 🥘 **Mealie** | A self-hosted recipe manager and meal planner with features like shopping lists, scaling, and importing. | [Details](services/mealie) |
| 🥘 **Tandoor Recipes** | A self-hosted recipe manager that also serves as a meal planner that has features such as nutrient tracking, shopping lists, importing and AI. | [Details](services/tandoor) |

Expand Down Expand Up @@ -273,4 +274,4 @@ See [CONTRIBUTING.md](/CONTRIBUTING.md) for guidance on adding services with the

## License

[MIT](https://choosealicense.com/licenses/mit/)
[MIT](https://choosealicense.com/licenses/mit/)
29 changes: 29 additions & 0 deletions services/kitchenowl/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#version=1.1
#URL=https://github.com/tailscale-dev/ScaleTail
#COMPOSE_PROJECT_NAME= # Optional: only use when running multiple deployments on the same infrastructure.

# Service Configuration
SERVICE=kitchenowl
IMAGE_URL=tombursch/kitchenowl:latest

# Network Configuration
SERVICEPORT=8080
DNS_SERVER=9.9.9.9

# Tailscale Configuration
TS_AUTHKEY= # Auth key from https://tailscale.com/admin/authkeys. See: https://tailscale.com/kb/1085/auth-keys#generate-an-auth-key for instructions.

# Time Zone setting for containers
TZ=Europe/Amsterdam # See: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones

# Optional Service variables
# PUID=1000

#EXAMPLE_VAR="Environment varibale"

JWT_SECRET_KEY= # Generate a random string for JWT secret key, e.g., using: openssl rand -base64 32

FRONT_URL=https://kitchenowl.<YOUR_TAILSCALE_DOMAIN>.ts.net # the exact URL of your kitchenowl instance, required when using OIDC authentication, e.g https://kitchenowl.example.com
#OIDC_ISSUER= # your OIDC issuer, e.g https://accounts.google.com
#OIDC_CLIENT_ID= # to be generated by your OIDC provider
#OIDC_CLIENT_SECRET= # to be generated by your OIDC provider
58 changes: 58 additions & 0 deletions services/kitchenowl/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# Kitchenowl with Tailscale Sidecar Configuration

This Docker Compose configuration sets up **Kitchenowl** with a Tailscale sidecar container, enabling secure, private access to your self-hosted grocery list, recipe manager, and meal planner over your Tailnet. With this setup, your Kitchenowl instance is **not exposed to the public internet** and is only accessible from authorized devices connected via Tailscale.

## Kitchenowl

[**Kitchenowl**](https://github.com/TomBursch/kitchenowl) is a self-hosted grocery list, recipe manager, and meal planning application designed for households and shared kitchens. It helps you organize shopping lists, recipes, weekly meal plans, pantry items, and household food planning from a central web interface.

Kitchenowl is useful for families, housemates, and home labs that want a private alternative to cloud-hosted grocery and recipe apps. It supports collaborative lists, recipe import workflows, meal planning, and optional account integration features, making it a practical tool for day-to-day kitchen organization.

## Key Features

- 🛒 Shared grocery lists for households and teams
- 🍽️ Recipe management with rich recipe import options
- 📅 Weekly meal planning for organizing upcoming meals
- 💸 Expense tracking for grocery and household food costs
- 🧺 Pantry and household item organization
- 👥 Multi-user collaboration for shared kitchens
- 🔐 Optional OpenID Connect support for external authentication
- 🛡️ Tailnet-only access when paired with the included Tailscale sidecar

## Tailscale Integration

This setup uses a **Tailscale sidecar container** to provide secure private networking for Kitchenowl. The Kitchenowl container shares the Tailscale container's network stack using Docker's `network_mode: service:<tailscale-service-name>` pattern.

Because of this, Kitchenowl does not need to publish ports directly to the host. Instead, you access the web interface through the Tailscale hostname or Tailnet IP assigned to the sidecar. This keeps the service private, reduces exposure, and avoids the need for public DNS, inbound firewall rules, or a public reverse proxy.

## Configuration Overview

The Compose stack is built around two services:

1. **Tailscale sidecar**
Handles authentication to your Tailnet and provides the private network endpoint for the application.

2. **Kitchenowl application**
Runs the Kitchenowl web interface and uses the Tailscale sidecar's network namespace for secure Tailnet-only access.

Kitchenowl should be configured with persistent storage so recipes, shopping lists, users, pantry data, meal plans, and application settings are retained across container restarts and updates. Review the provided `compose.yaml` and `.env` file before deployment, especially if you want to enable authentication integrations.

## OpenID Connect

Kitchenowl supports OpenID Connect for external authentication providers. This can be useful when integrating Kitchenowl with an existing identity provider such as Authentik, Authelia, Keycloak, or another OIDC-compatible service.

To enable OIDC in this ScaleTail service, review the commented OIDC sections in both the `.env` file and the `compose.yaml` file. Uncomment the relevant values and fill in the required provider details before starting the stack.

You can find the upstream Kitchenowl OIDC documentation here: [Kitchenowl OpenID Connect Documentation](https://docs.kitchenowl.org/latest/self-hosting/oidc/).

## Usage Notes

Once logged in, create your household, configure users, and begin adding grocery lists, recipes, pantry items, and meal plans. Since Kitchenowl is designed for shared household use, review user permissions and authentication settings before inviting other people to the instance.

## References

- [Kitchenowl Website](https://kitchenowl.org/)
- [Kitchenowl GitHub Repository](https://github.com/TomBursch/kitchenowl)
- [Kitchenowl Documentation](https://docs.kitchenowl.org/)
- [Kitchenowl OpenID Connect Documentation](https://docs.kitchenowl.org/latest/self-hosting/oidc/)
- [Tailscale Docker Documentation](https://tailscale.com/kb/1282/docker)
68 changes: 68 additions & 0 deletions services/kitchenowl/compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
configs:
ts-serve:
content: |
{"TCP":{"443":{"HTTPS":true}},
"Web":{"$${TS_CERT_DOMAIN}:443":
{"Handlers":{"/":
{"Proxy":"http://127.0.0.1:8080"}}}},
"AllowFunnel":{"$${TS_CERT_DOMAIN}:443":false}}

services:
# Make sure you have updated/checked the .env file with the correct variables.
# All the ${ xx } need to be defined there.
# Tailscale Sidecar Configuration
tailscale:
image: tailscale/tailscale:latest # Image to be used
container_name: tailscale-${SERVICE} # Name for local container management
hostname: ${SERVICE} # Name used within your Tailscale environment
environment:
- TS_AUTHKEY=${TS_AUTHKEY}
- TS_STATE_DIR=/var/lib/tailscale
- TS_SERVE_CONFIG=/config/serve.json # Tailscale Serve configuration to expose the web interface on your local Tailnet - remove this line if not required
- TS_USERSPACE=false
- TS_ENABLE_HEALTH_CHECK=true # Enable healthcheck endpoint: "/healthz"
- TS_LOCAL_ADDR_PORT=127.0.0.1:41234 # The <addr>:<port> for the healthz endpoint
#- TS_ACCEPT_DNS=true # Uncomment when using MagicDNS
- TS_AUTH_ONCE=true
configs:
- source: ts-serve
target: /config/serve.json
volumes:
- ./config:/config # Config folder used to store Tailscale files - you may need to change the path
- ./ts/state:/var/lib/tailscale # Tailscale requirement - you may need to change the path
devices:
- /dev/net/tun:/dev/net/tun # Network configuration for Tailscale to work
cap_add:
- net_admin # Tailscale requirement
ports:
- 0.0.0.0:${SERVICEPORT}:${SERVICEPORT} # Binding port ${SERVICE}PORT to the local network - may be removed if only exposure to your Tailnet is required
# If any DNS issues arise, use your preferred DNS provider by uncommenting the config below
# dns:
# - ${DNS_SERVER}
healthcheck:
test: ["CMD", "wget", "--spider", "-q", "http://127.0.0.1:41234/healthz"] # Check Tailscale has a Tailnet IP and is operational
interval: 1m # How often to perform the check
timeout: 10s # Time to wait for the check to succeed
retries: 3 # Number of retries before marking as unhealthy
start_period: 10s # Time to wait before starting health checks
restart: always

# ${SERVICE}
kitchenowl:
image: ${IMAGE_URL} # Image to be used
network_mode: service:tailscale # Sidecar configuration to route ${SERVICE} through Tailscale
container_name: app-${SERVICE} # Name for local container management
env_file: .env
volumes:
- ./${SERVICE}-data/:/data
environment:
- JWT_SECRET_KEY=${JWT_SECRET_KEY} # JWT secret key for authentication - make sure to set this in the .env file
## Optional for OIDC support - make sure to set these in the .env file if required!
#- FRONT_URL=${FRONT_URL}
#- OIDC_ISSUER=${OIDC_ISSUER}
#- OIDC_CLIENT_ID=${OIDC_CLIENT_ID}
#- OIDC_CLIENT_SECRET=${OIDC_CLIENT_SECRET}
depends_on:
tailscale:
condition: service_healthy
restart: unless-stopped