Applications AWS

Bar Assistant Cocktail Manager on AWS User Guide

| Product: Bar Assistant Self-Hosted Cocktail Manager

Overview

This guide covers the deployment and configuration of Bar Assistant on AWS using cloudimg AWS Marketplace AMIs. Bar Assistant is an open source, all-in-one solution for organising cocktail recipes and tracking a home bar. You build a catalogue of ingredients and the bottles you own, and it works out which cocktails you can make, lets you scale, cost and tag recipes, keep tasting notes and shopping lists, and publish a shareable menu. It pairs a Laravel REST API with the Salt Rim browser client for searching, filtering and editing your collection, and uses Meilisearch so lookups across recipes and ingredients are instant.

The cloudimg image ships the free and open source, MIT-licensed Bar Assistant server, the MIT-licensed Salt Rim web client and the MIT-licensed Meilisearch engine, run the officially supported way as the upstream containers pinned by image digest. All three images are captured into the AMI, so your instance starts in seconds. Because the upstream project ships with open registration and search wide open, nothing here ships with a known secret: a unique Laravel application key, a unique Meilisearch master key and a per-instance admin account with a random password are generated for each instance on first boot, before the app is reachable, and the search engine refuses any request without a key. Backed by 24/7 cloudimg support.

Bar Assistant, Salt Rim and Meilisearch are trademarks of their respective owners. This image is produced by cloudimg and is not affiliated with, endorsed by, or sponsored by any of them. It ships the free and open source MIT-licensed self-hosted software, unmodified.

What is included:

  • Bar Assistant server v5 (the MIT-licensed Laravel API), pinned by image digest
  • Salt Rim web client v4 (the MIT-licensed Vue browser client), pinned by image digest
  • Meilisearch v1.15 (the MIT-licensed search engine) running in production mode, so every request requires a key
  • A SQLite application database, created empty on first boot and stored on a persistent volume
  • Docker Engine with the API, web client and search engine published to the loopback interface only, fronted by nginx on port 80 at / (web client), /bar (API) and /search (search)
  • bar-assistant.service, bar-assistant-firstboot.service, bar-assistant-postboot.service and nginx.service as systemd units, enabled and active on boot
  • A unique Laravel application key, a unique Meilisearch master key and a per-instance admin account with a random password generated per instance on first boot, never baked into the image
  • No default login, no shipped secret and an empty database on first boot
  • Ubuntu 24.04 LTS base with latest security patches applied at build time
  • 24/7 cloudimg support with a guaranteed 24-hour response SLA

Prerequisites

  • An active AWS account and an EC2 key pair in your target region
  • A subscription to the Bar Assistant listing on AWS Marketplace
  • A VPC and subnet, and a security group allowing inbound 22/tcp (SSH, from your admin network) and 80/tcp (the web client, from the networks that use it)

Recommended instance type: m5.large (2 vCPU, 8 GB RAM) is a sensible starting point for a household or an enthusiast. For larger collections or many concurrent users, use a larger instance. The web client, API and search engine are lightweight, so a general-purpose instance is ample.

Connecting to your instance

This listing offers one or more operating-system variants. Connect over SSH as that variant's default login user, using your EC2 key pair:

OS variant SSH login user Example
Ubuntu 24.04 LTS ubuntu ssh -i your-key.pem ubuntu@<instance-public-ip>

Step 1: Subscribe and launch from AWS Marketplace

Sign in to the AWS Marketplace, search for Bar Assistant by cloudimg, and choose Continue to Subscribe, then Continue to Configuration and Continue to Launch. Pick your region, the m5.large instance type, your VPC and subnet, your EC2 key pair, and a security group that allows SSH (22) from your admin network and HTTP (80) from the networks that use the app. Launch the instance.

Step 2: Launch from the AWS CLI

You can also launch the AMI directly. Resolve the product AMI id for your region from the listing, then:

REGION="us-east-1"
AMI_ID="<ami-id>"          # the Bar Assistant AMI id for your region
KEY_NAME="your-key"
SG_ID="sg-xxxxxxxx"         # allows 22 from your admin CIDR and 80 from your users
SUBNET_ID="subnet-xxxxxxxx"
aws ec2 run-instances --region "$REGION" \
  --image-id "$AMI_ID" --instance-type m5.large \
  --key-name "$KEY_NAME" --security-group-ids "$SG_ID" --subnet-id "$SUBNET_ID" \
  --metadata-options 'HttpTokens=required,HttpEndpoint=enabled' \
  --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=bar-assistant}]'

The image resolves its public URLs from EC2 instance metadata (IMDSv2) on first boot, so the web client and API are reachable at the instance's public address with no extra configuration.

Step 3: Connect to your instance

ssh -i your-key.pem ubuntu@<public-ip>

Step 4: Confirm the services are running

The stack runs as three containers (the Bar Assistant server, Meilisearch and the Salt Rim web client) under one bar-assistant.service, fronted by nginx. Confirm the services are active and see the containers. nginx listens on :80; the API, search engine and web client are each published to 127.0.0.1 only:

sudo systemctl is-active docker bar-assistant nginx
sudo docker compose -f /etc/barassistant/compose.yaml ps

You will see the services report active and the three containers running. The API (127.0.0.1:8082), Meilisearch (127.0.0.1:8081) and the Salt Rim client (127.0.0.1:8083) are bound only to the loopback interface; nginx on :80 is the single public front door and routes / to the web client, /bar to the API and /search to Meilisearch.

Step 5: Read the per-instance credentials

A unique Laravel application key, a unique Meilisearch master key and a per-instance admin account with a random password were generated for this instance on the first boot, before the app was reachable, and written to a root-only file. Read them:

sudo cat /root/bar-assistant-credentials.txt

The file (mode 0600 root:root) holds ADMIN_EMAIL and ADMIN_PASSWORD (the account you sign in to the web client with), plus WEB_URL, API_URL, the APP_KEY and the MEILI_MASTER_KEY. None of these ship in the image; every value is unique to this instance, so no two instances share a credential and there is no default login to change.

Step 6: Verify the security model

The web client and the public API version endpoint are reachable without authentication, but every protected API endpoint requires a bearer token, and Meilisearch refuses any request without a key. Confirm that the web client loads, that an unauthenticated request to a protected endpoint is rejected with 401, and that the per-instance admin credential authenticates a real call:

ADMIN_EMAIL=$(sudo grep '^ADMIN_EMAIL=' /root/bar-assistant-credentials.txt | cut -d= -f2-)
ADMIN_PASSWORD=$(sudo grep '^ADMIN_PASSWORD=' /root/bar-assistant-credentials.txt | cut -d= -f2-)
curl -s -o /dev/null -w 'web client    (no auth):  %{http_code}\n' http://localhost/
curl -s -o /dev/null -w 'search        (no key):   %{http_code}\n' http://localhost/search/indexes
curl -s -o /dev/null -w 'profile       (no token): %{http_code}\n' -H 'Accept: application/json' http://localhost/bar/api/profile
TOKEN=$(curl -s -X POST http://localhost/bar/api/auth/login \
  -H 'Content-Type: application/json' -H 'Accept: application/json' \
  -d "{\"email\":\"$ADMIN_EMAIL\",\"password\":\"$ADMIN_PASSWORD\"}" | python3 -c 'import sys,json;print(json.load(sys.stdin)["data"]["token"])')
curl -s -o /dev/null -w 'profile       (with token): %{http_code}\n' \
  -H "Authorization: Bearer $TOKEN" -H 'Accept: application/json' http://localhost/bar/api/profile

The web client returns 200, Meilisearch rejects the unauthenticated request with 401 (it is key-gated), the protected profile endpoint is rejected with 401 for no token, and the same call with the per-instance admin token returns 200. This is the security model: the web client and the search engine are locked down, and the API is gated by a bearer token you obtain by signing in.

The same round trip is bundled as a single script on the image, which the build and smoke tests run to prove the credential works end to end:

sudo /usr/local/sbin/bar-assistant-roundtrip.sh

Step 7: Open the web client and sign in

Browse to http://<instance-public-ip>/ to reach the Salt Rim web client. Sign in with the ADMIN_EMAIL and ADMIN_PASSWORD from Step 5. New users can also self-register with the Register button (this is on by default; see Step 11 to disable open registration).

The Salt Rim sign-in page for Bar Assistant, with the email and password fields, a Remember me option, and the Login and Register buttons

Step 8: Create your first bar and import recipes

After signing in, create a bar (your workspace for a collection of cocktails and ingredients) and choose to import the bundled base data. Bar Assistant then loads several hundred classic cocktail recipes and their ingredients, so you have a populated library to explore immediately. The home dashboard shows your bar statistics, the latest cocktails and recommendations based on what is on your shelf.

Step 9: Browse and search your cocktails

Open Cocktails to browse the library as a grid of recipe cards with photos, ratings, ingredients and tags. Use the search box (powered by Meilisearch) to find a recipe instantly, filter by ingredient, tag or method, and sort the list. Mark what is on your Shelf and Bar Assistant highlights the cocktails you can make right now.

The Bar Assistant cocktails page showing a grid of cocktail recipe cards, each with a photo, name, star rating, ingredient list and tags, plus a search box and filter and sort controls

Step 10: Track your ingredients

Open Ingredients to browse the ingredient library, each entry with a category, an image and a description. Add ingredients to your bar shelf to record what you own, or to your shopping list for what you need. With your shelf populated, Bar Assistant works out which cocktails you can make right now.

The Bar Assistant ingredients page showing a grid of ingredient cards, each with an image, name, category and description, and links to add each one to the bar shelf or the shopping list

Step 11: Open a recipe

Select any cocktail to open its recipe: the photo, description, glass type, method, ABV and the full ingredient list with measurements, which you can scale and switch between millilitres, ounces and centilitres. Add tasting notes, rate it, add missing ingredients to your shopping list, or edit and add your own recipes.

A single cocktail recipe detail view in Bar Assistant, showing the Gin Fizz with its photo, description, tags, glass type, method, ABV and the scaled ingredient list with measurements

Step 12: Manage registration and users

Open registration is enabled by default so household members can create their own accounts. To close registration once your users are set up, edit /etc/barassistant/compose.yaml, set ALLOW_REGISTRATION to "false" on both the bar-assistant and salt-rim services, and restart the stack:

sudo systemctl restart bar-assistant

Each user manages their own profile and password in Settings; a bar owner can invite members and assign roles to share a bar.

Step 13: Call the API from your own machine

Every feature of the web client is backed by the REST API, which you can call directly. Obtain a token by signing in, then call a protected endpoint with the instance address:

TOKEN=$(curl -s -X POST http://<public-ip>/bar/api/auth/login \
  -H 'Content-Type: application/json' -H 'Accept: application/json' \
  -d '{"email":"<ADMIN_EMAIL>","password":"<ADMIN_PASSWORD>"}' | python3 -c 'import sys,json;print(json.load(sys.stdin)["data"]["token"])')
curl -s -H "Authorization: Bearer $TOKEN" -H 'Accept: application/json' -H 'Bar-Assistant-Bar-Id: 1' \
  "http://<public-ip>/bar/api/cocktails?per_page=5"

The login returns a bearer token; protected list endpoints take a Bar-Assistant-Bar-Id header to select which bar to query. The full API is documented at http://<instance-public-ip>/bar/api/server/openapi.

Step 14: Server components

Component Version / Detail
API server Bar Assistant server v5 (Laravel, pinned by image digest)
Web client Salt Rim v4 (Vue, pinned by image digest)
Search engine Meilisearch v1.15 (production mode, key required)
Front door nginx on :80 routing / to the client, /bar to the API, /search to search
Application database SQLite (created empty on first boot, on a persistent volume)
Orchestration Docker Compose under bar-assistant.service
Application key per instance, generated first boot into /etc/barassistant/bar.env
Admin account per instance random password, seeded first boot into /root/bar-assistant-credentials.txt
Operating system Ubuntu 24.04 LTS (patched at build)
License MIT (Bar Assistant, Salt Rim, Meilisearch)

Step 15: Managing the service

sudo systemctl status bar-assistant --no-pager | head -12
sudo docker compose -f /etc/barassistant/compose.yaml logs --tail 40 bar-assistant

Restart the whole stack with sudo systemctl restart bar-assistant, follow the API logs live with sudo docker compose -f /etc/barassistant/compose.yaml logs -f bar-assistant, and view configuration in /etc/barassistant/bar.env and /etc/barassistant/compose.yaml. After changing the environment file, restart the service to apply it.

Step 16: Use your own domain and HTTPS (production)

The image serves the web client and API over plain HTTP on port 80, which is convenient behind a load balancer or private network. For production you should terminate TLS in front of the instance so credentials travel encrypted:

  • Front the instance with an Application Load Balancer with an AWS Certificate Manager certificate, or a CloudFront distribution, and forward to nginx on port 80.
  • Or install your own certificate: add a TLS server block to /etc/nginx/sites-available/bar-assistant referencing your certificate and key, open 443/tcp on the security group, then sudo systemctl reload nginx.
  • Point a DNS name you control at the instance. Because the web client reads its API and search URLs at first boot from the resolved public address, use a stable Elastic IP or set the address before first boot when using a custom domain.

Step 17: Security recommendations

  • Restrict the security group. Allow TCP 80 (and 22 for admin) only from the networks that use the app.
  • Terminate TLS in front of the app (Step 16) so the admin password and tokens are encrypted in transit.
  • Rotate the seeded admin password. Sign in and change it in Settings, and close open registration (Step 12) once your users exist.
  • Keep the search engine and API private. Meilisearch and the API are bound to loopback and fronted by nginx; keep them that way and never expose the container ports directly.
  • Keep the OS patched. Unattended security upgrades remain enabled on the running instance.

Step 18: Support and Licensing

Bar Assistant, Salt Rim and Meilisearch are each distributed under the MIT License. This cloudimg image bundles the unmodified official open source releases; cloudimg provides the packaging, the single nginx front door, the per-instance key and admin generation, the paired deploy guide, and 24/7 support with a guaranteed 24-hour response SLA. Bar Assistant is an independent open source project and this image is not affiliated with or endorsed by it.

Deploy on AWS

Launch Bar Assistant by cloudimg from AWS Marketplace and follow this guide to a working cocktail and home-bar manager in minutes.