the personal food nutrition journal
Go to file
Christopher C. Wells 153611e66d Remove Goal `from` and `to` attributes 2021-05-15 21:40:53 -07:00
.github Rename CI env file 2021-04-09 15:17:13 -07:00
app Remove Goal `from` and `to` attributes 2021-05-15 21:40:53 -07:00
bootstrap Initial commit -- Laravel base app 2020-12-21 09:46:31 -08:00
config Add support for S3 media storage 2021-04-22 13:23:10 -07:00
database Remove Goal `from` and `to` attributes 2021-05-15 21:40:53 -07:00
elastic/migrations Use babenkoivan Elasticsearch ecosystem 2021-03-04 22:17:33 -08:00
public Add remaining fields for Goal edit form 2021-05-15 21:40:53 -07:00
resources Remove Goal `from` and `to` attributes 2021-05-15 21:40:53 -07:00
routes Add dev console command to reset database 2021-04-22 10:27:19 -07:00
storage Remove media handling from database seeder 2021-04-08 07:49:33 -07:00
tests Update `user:add` command for User model changes 2021-04-22 15:10:38 -07:00
.dockerignore Only include necessary files in docker image 2021-04-24 14:07:08 -07:00
.editorconfig Initial commit -- Laravel base app 2020-12-21 09:46:31 -08:00
.env.ci Correct default `MEDIA_DISK` setting 2021-04-24 09:29:38 -07:00
.env.example Correct default `MEDIA_DISK` setting 2021-04-24 09:29:38 -07:00
.gitattributes Initial commit -- Laravel base app 2020-12-21 09:46:31 -08:00
.gitignore Move production docker compose config to separate repo 2021-04-23 21:45:44 -07:00
.phpstorm.meta.php Add support for S3 media storage 2021-04-22 13:23:10 -07:00
.styleci.yml Initial commit -- Laravel base app 2020-12-21 09:46:31 -08:00
ATTRIBUTIONS.md Remove icon nav elements 2021-03-27 21:01:34 -07:00
Dockerfile Add Media Library deps to Dockerfile 2021-04-24 09:40:43 -07:00
LICENSE Add LICENSE file 2021-01-03 14:30:18 -08:00
Procfile Add Heroku support (#12) 2021-04-06 10:05:10 -07:00
README.md Fix some README issues 2021-04-24 14:19:44 -07:00
_ide_helper.php Update Composer dependencies 2021-04-20 11:56:33 -07:00
app.json Set default user as admin in Heroku post deploy 2021-04-22 15:10:54 -07:00
artisan Initial commit -- Laravel base app 2020-12-21 09:46:31 -08:00
composer.json Add support for S3 media storage 2021-04-22 13:23:10 -07:00
composer.lock Add support for S3 media storage 2021-04-22 13:23:10 -07:00
docker-compose.yml Move production docker compose config to separate repo 2021-04-23 21:45:44 -07:00
package-lock.json Update Node dependencies; enable Tailwind JIT 2021-04-20 12:16:46 -07:00
package.json Update Node dependencies; enable Tailwind JIT 2021-04-20 12:16:46 -07:00
phpstan.neon.dist Add phpstan support 2021-01-24 19:43:59 -08:00
phpunit.xml.dist Remove ElasticSearch setting for PHPUnit config 2021-04-09 15:28:49 -07:00
screenshot-mobile.png Add demo and other updates to README 2021-04-08 14:47:07 -07:00
screenshot.png Add demo and other updates to README 2021-04-08 14:47:07 -07:00
server.php Initial commit -- Laravel base app 2020-12-21 09:46:31 -08:00
tailwind.config.js Update Node dependencies; enable Tailwind JIT 2021-04-20 12:16:46 -07:00
webpack.mix.js Add Quill editor for recipe description 2021-03-08 08:40:36 -08:00

README.md

kcal the personal food nutrition journal

License: MPL 2.0 CI Status Coverage Status

Track nutritional information about foods and recipes, set goals, and record a food journal to help along the way. Kcal is a personal system that focuses on direct control of inputs (as opposed to unwieldy user generated datasets) and a minimal, easy to use recipe presentation for preparing meals.

Demo

A demo of kcal is available on Heroku. Login credentials are:

  • Username: kcal
  • Password: kcal

The demo instance resets every hour, on the hour.

Screenshots

Baby Buddy mobile view Baby Buddy desktop view

Deployment

Docker

There is a Dockerfile and automated build process to create builds at kcalapp/kcal on Docker Hub. See the kcal-app/kcal-docker repository for a Docker Compose based template and instructions.

Heroku

Deploy

The default username and password for a Heroku deployment is kcal/kcal.

Using Heroku CLI

For a manual deploy using Heroku CLI, execute the following after initial deployment:

heroku run php artisan migrate
heroku run php artisan user:add
heroku config:set APP_KEY=$(php artisan --no-ansi key:generate --show)

Media storage

Heroku uses an ephemeral disk. In order to maintain recipe and/or user images between app restarts AWS can be used. See Media Storage - AWS S3 for additional guidance.

Search drivers

See the Search section for information about supported drivers. Additional environment variable configuration is necessary when using any search driver other than the default ("null").

Redis Add-on

The Heroku Redis add-on can be added to the app and will work without any configuration changes. It is left out of the default build only because it takes a very long time to provision.

Configuration

Media Storage

Recipes and users can have associated media (images) that by default are stored on a local disk under the path {app}/public/media. If a local disk solution is not feasible, an AWS S3 bucket can be used instead.

AWS S3

Use the general guidance below to create an AWS S3 bucket and IAM user for media storage in AWS S3.

  1. Create a bucket that allows objects to be configured with public access.

  2. Create an IAM user with access to the bucket.

    Use this example policy to grant necessary permissions to a specific bucket:

     {
         "Version": "2012-10-17",
         "Statement": [
             {
                "Sid": "VisualEditor0",
                "Effect": "Allow",
                "Action": [
                    "s3:GetBucketPublicAccessBlock",
                    "s3:GetBucketPolicyStatus",
                    "s3:GetAccountPublicAccessBlock",
                    "s3:ListAllMyBuckets",
                    "s3:GetBucketAcl",
                    "s3:GetBucketLocation"
                ],
                "Resource": "*"
            },
            {
                "Sid": "VisualEditor1",
                "Effect": "Allow",
                "Action": "s3:ListBucket",
                "Resource": "arn:aws:s3:::REPLACE_WITH_S3_BUCKET_NAME"
            },
            {
                "Sid": "VisualEditor2",
                "Effect": "Allow",
                "Action": ["s3:*Object", "s3:*ObjectAcl*"],
                "Resource": "arn:aws:s3:::REPLACE_WITH_S3_BUCKET_NAME/*"
            }
         ]
     }
    
  3. Set necessary environment variables (via .env or some other mechanism).

     MEDIA_DISK=s3-public
     AWS_ACCESS_KEY_ID=REPLACE_WITH_IAM_KEY
     AWS_SECRET_ACCESS_KEY=REPLACE_WITH_IAM_SECRET
     AWS_DEFAULT_REGION=REPLACE_WITH_S3_BUCKET_NAME
     AWS_BUCKET=REPLACE_WITH_S3_BUCKET_REGION
    

Search 🔍

The "ingredient" (food or recipe) search for journal entries and recipe ingredients supports three different backends using the SCOUT_DRIVER environment variable. In all cases, always ensure that the SCOUT_DRIVER environment variable is only set once in kcal's .env file.

Currently, the food and recipe list searches do not take advantage of these search drivers. Support for those searches will be added if the Laravel JSON:API adds support for Scout (see: laravel-json-api/laravel#32).

Algolia (algolia)

  1. Create and/or log in to an Algolia account.

  2. Create an application for kcal.

  3. Navigate to the application's "API Keys" section.

  4. Using the Application ID and Admin API Key values, update kcal's .env file:

     SCOUT_DRIVER=algolia
     ALGOLIA_APP_ID=<APPLICATION_ID>
     ALGOLIA_SECRET=<ADMIN_API_KEY>
    

ElasticSearch (elastic)

  1. Determine the ElasticSearch service host and port.

  2. Update kcal's .env file.

     SCOUT_DRIVER=elastic
     ELASTIC_HOST=<HOST:PORT>
     ELASTIC_PORT=<PORT>
    

    Note: The ELASTIC_PORT variable is a convenience option specifically for Docker Compose configurations and is not strictly required.

  3. Run Elastic's migrations.

     php artisan elastic:migrate
    

Fallback (null)

The fallback driver is a simple WHERE ... LIKE clause search on a couple of key fields. Results will not be ordered by relevance, and some fields will not be searched (e.g. the tags fields). Using one of the other options is highly recommended.

Set SCOUT_DRIVER=null in kcal's .env file to use the fallback driver.

Development

Laravel Sail

Prerequisites

Steps

  1. Clone the repository.

     git clone https://github.com/kcal-app/kcal.git
     cd kcal
    
  2. Install development dependencies.

     composer install
    
  3. Create a local .env file.

     cp .env.local.example .env
    
  4. Generate an app key.

     php artisan key:generate
    

    Verify that the APP_KEY variable has been set in .env. If has not, run php artisan key:generate --show and copy the key and append it to the APP_KEY= line manually.

  5. Run it!

     vendor/bin/sail up
    
  6. (On first run) Run migrations.

     vendor/bin/sail artisan migrate
     vendor/bin/sail artisan elastic:migrate
    
  7. (On first run) Seed the database.

     vendor/bin/sail artisan db:seed
    

    The default username and password is kcal / kcal.

Navigate to http://127.0.0.1:8080 to log in!

Create a docker-compose.override.yml file to override any of the default settings provided for this environment.

Testing

Ensure that Sail is running (primarily to provide ElasticSearch):

vendor/bin/sail up -d

Execute tests.

vendor/bin/sail artisan test --parallel

Caveats

In order to support parallel testing, tests are run using sqlite (even though Sail provides MySQL). To test with MySQL make a copy of phpunit.xml.dist as phpunit.xml and change:

<server name="DB_CONNECTION" value="sqlite"/>
<server name="DB_DATABASE" value=":memory:"/>

to

<server name="DB_CONNECTION" value="mysql"/>
<server name="DB_HOST" value="db"/>

Now running vendor/bin/sail artisan test will run tests with MySQL but tests cannot be run in parallel.