All apps · 0 apps
ai-marketplace-monitor
Docker app from UnraidUser-5377155957's Repository
Overview
Readme
View on GitHubThe Docker image runs aimm on a server, a NAS or any machine without a screen. It bundles Python, Playwright Chromium, a virtual display and a noVNC client, so you can complete Facebook's CAPTCHA or security code from the web UI. You can start it with a single docker run command, or with Docker Compose: the repository's docker-compose/ folder has docker-compose.yml, which you use as is, and .env.example, a template for the .env file that holds your credentials and settings.
Prerequisites
- Docker Engine with the Compose plugin (
docker compose versionprints a version) - A Facebook account for aimm to log in with
- For the default configuration, a UnitySVC account and an API key (
svcpass_...), forUNITYSVC_API_KEY. Sign up at unitysvc.com and create an API key in your account. If you configure other providers directly instead (see below), you do not need them.
Why a UnitySVC key
The default configuration needs only this one key, for both the AI that rates listings and the email and phone/chat notifications:
- AI from any provider: OpenAI, Anthropic and other AI engines, either as UnitySVC platform services or with your own provider keys (BYOK, "bring your own key"). For BYOK, save the provider's key once as a secret in your UnitySVC account (Developer → Secrets, e.g.
OPENAI_API_KEY); it stays in UnitySVC, and your aimm configuration and.envstill hold onlyUNITYSVC_API_KEY. See AI Services. - Notifications: email with photos and short messages to your phone, Discord, Slack and 100+ other channels, through UnitySVC's platform services or your own accounts. See UnitySVC notification.
You can also skip UnitySVC and configure OpenAI, Gmail and other services in config.toml directly, with their keys in .env.
Quick start with docker run
If aimm is already installed on this machine, or you prefer to keep your credentials in environment variables, run:
docker run -d --name aimm \
-p 8467:8467 \
-v "$HOME/.ai-marketplace-monitor:/data" \
-e FACEBOOK_USERNAME -e FACEBOOK_PASSWORD \
-e UNITYSVC_API_KEY \
--restart unless-stopped \
ghcr.io/bopeng/ai-marketplace-monitor:latest
The -e flags pass FACEBOOK_USERNAME, FACEBOOK_PASSWORD and UNITYSVC_API_KEY (if you use UnitySVC) from your shell to the container; config.toml refers to them as ${FACEBOOK_USERNAME} and so on. Make sure they contain only the intended values: when Docker exposes the web UI, the Facebook username and password also protect it and its browser view.
Mounting ~/.ai-marketplace-monitor at /data shares your existing config, cache and logs between an aimm installed on the host and the container, so you can switch between them, one at a time (see Troubleshooting below). aimm runs in the container as an unprivileged user with ID 1000. On a Linux host where your user ID is not 1000 (see id -u), add -e PUID="$(id -u)" -e PGID="$(id -g)" so that the files in the folder stay yours; Docker Desktop on macOS and Windows does not need it. If you created the container with the folder mounted at /root/.ai-marketplace-monitor, as older versions of this guide said, it still works, and the log asks you to mount it at /data instead. Continue with First run below; in the commands there, use docker exec aimm ... instead of docker compose exec aimm ..., and docker logs aimm to see the log.
To build the image yourself instead of pulling it, run docker build -f docker/Dockerfile -t aimm . from the root of a checkout of the repository.
Set up with Docker Compose
Create a directory for aimm, for example ~/aimm, and download the two files into it:
mkdir -p ~/aimm && cd ~/aimm
curl -fsSLO https://raw.githubusercontent.com/BoPeng/ai-marketplace-monitor/main/docker-compose/docker-compose.yml
curl -fsSL -o .env https://raw.githubusercontent.com/BoPeng/ai-marketplace-monitor/main/docker-compose/.env.example
chmod 600 .env
Edit .env and fill in FACEBOOK_USERNAME, FACEBOOK_PASSWORD, UNITYSVC_API_KEY and your time zone, TZ. Keep each value in single quotes so that a $ in a password is not read as a variable. Every variable in .env reaches aimm, so an API key for another provider only needs a line there too.
aimm runs in the container as an unprivileged user with ID 1000 and keeps its config, cache and logs in ./data. When it starts, it gives ./data to that user. On a Linux host where your user ID is not 1000 (see id -u), set PUID and PGID in .env to your user and group IDs, so that the files in ./data stay yours. Docker Desktop on macOS and Windows does not need them. If your platform starts containers as a fixed user instead (user: in Compose), give ./data to that user.
Then start aimm:
docker compose up -d
docker compose logs -f aimm
NAS and container managers
The sections below install aimm on NAS and home-server systems and with container managers, from the templates in the repository's deploy/ folder. On every platform, aimm keeps its config, cache and logs in the folder or volume mounted at /data, and you continue with First run below.
Synology and QNAP have no app store for Docker apps; their container managers run Docker Compose files, and their image search finds aimm on Docker Hub as bopeng/ai-marketplace-monitor (amd64 and arm64, the same tags as ghcr.io/bopeng/ai-marketplace-monitor).
Synology (Container Manager, DSM 7.2 or later)
Container Manager runs a Project inside a folder, so the files from Set up with Docker Compose above work as they are, .env included:
- In File Station, create a folder for aimm, for example
docker/aimm. Uploaddocker-compose.ymland.env.exampleto it, then rename.env.exampleto.envin File Station (a file whose name starts with a dot is hard to create on a computer). Fill in.envbefore uploading it, or with the Text Editor package. - Set
PUIDandPGIDin.envto the user that should own aimm's files. Over SSH,id <user>shows them; the first user created on DSM is usually1026, groupusers(100). - Container Manager › Project › Create: give it a name, choose the folder as its path, select Use existing docker-compose.yml, and finish the wizard. Container Manager pulls the image and starts aimm; the
datafolder appears next to the files. - Open
http://<NAS address>:8467and continue with First run below. The project's Container tab shows the log.
To update, open the project, Action › Stop, then Action › Build (it pulls the newer image), and start it again.
QNAP (Container Station 3)
Container Station's Applications keep the YAML you paste in their own folder, so a .env file next to it is not read. Use a self-contained file instead:
In File Station, create a folder for aimm's data, for example
Container/aimm/data(the shareContaineris/share/Container).Find the IDs of the user that should own the files: over SSH,
id <user>. New QNAP users usually start at1000, groupeveryone(100).Container Station › Applications › Create, name it
aimm, and paste the following, with your values:services: aimm: image: bopeng/ai-marketplace-monitor:latest container_name: aimm restart: unless-stopped environment: FACEBOOK_USERNAME: "you@example.com" FACEBOOK_PASSWORD: "your-facebook-password" UNITYSVC_API_KEY: "svcpass_..." TZ: "America/Chicago" PUID: "1000" PGID: "100" ports: - "8467:8467" volumes: - /share/Container/aimm/data:/dataWrite any
$in a value as$$; Compose reads a single$as the start of a variable.Create, then open
http://<NAS address>:8467and continue with First run below. The application's container shows the log.
To update, open the application and choose Recreate (or remove it and create it again with the same YAML); the data folder keeps your config, cache and logs.
Unraid
Add aimm's template to Unraid, then create the container from it:
Open the terminal (>_ in the header) and save the template where Unraid keeps your own templates:
wget -O /boot/config/plugins/dockerMan/templates-user/my-ai-marketplace-monitor.xml https://raw.githubusercontent.com/BoPeng/ai-marketplace-monitor/main/deploy/unraid/ai-marketplace-monitor.xmlDocker › Add Container, and under Template choose ai-marketplace-monitor from the user templates.
Fill in the Facebook username and password, and replace the placeholder UnitySVC API key with yours. The data goes to
/mnt/user/appdata/ai-marketplace-monitor, owned by Unraid'snobody:users(99/100).Apply, then open the web UI from the container's icon.
To update, use Check for Updates on the Docker tab, then Apply update.
TrueNAS SCALE (Community Edition 24.10 or later)
Add aimm as a custom app: TrueNAS runs a Compose file that you paste, and deploy/truenas/install-via-yaml.yaml is one for aimm.
Datasets: select your pool, Add Dataset, name it
aimmand choose the Apps preset. The dataset then belongs to theappsuser (568), which aimm runs as.If you have not used apps yet, choose a pool for them: Apps › Configuration › Choose Pool.
Apps › Discover Apps, the ⋮ menu next to Custom App › Install via YAML. Name the app
aimmand paste the contents ofinstall-via-yaml.yaml:services: aimm: image: ghcr.io/bopeng/ai-marketplace-monitor:latest restart: unless-stopped user: "568:568" environment: FACEBOOK_USERNAME: "you@example.com" FACEBOOK_PASSWORD: "your-facebook-password" UNITYSVC_API_KEY: "svcpass_XXXXX" TZ: "America/Chicago" ports: - "8467:8467" volumes: - /mnt/<pool>/aimm:/dataReplace
<pool>with your pool's name, fill in your Facebook login, UnitySVC API key and time zone, and write any$in a value as$$.Save. When the app is Running, open
http://<TrueNAS address>:8467.
To change a setting later, open the app and choose Edit. TrueNAS notices when a newer image is published and offers an Update for the app, as for catalog apps; the dataset keeps your data.
CasaOS and ZimaOS
Import aimm's template:
- App Store, then Custom Install (the + at the top right) › Import.
- Paste the contents of
casaos/AIMarketplaceMonitor/docker-compose.ymland submit. CasaOS fills in the install form from it. - Fill in the Facebook username and password, and replace the placeholder UnitySVC API key with yours, before installing: the web UI does not start without the Facebook credentials. The data goes to
/DATA/AppData/<app>/data. - Install, then open aimm from its tile on the dashboard.
Cosmos
Import aimm's template: ServApps › Import Compose File, paste the contents of cosmos/AI-Marketplace-Monitor/cosmos-compose.json, and fill in the form it shows (the Facebook username and password, and your UnitySVC API key). Cosmos puts the data in a volume and serves the web UI through its reverse proxy.
Portainer
Portainer is a web interface for managing Docker containers and Compose stacks. Its App Templates come from one list, set in Settings › App Templates. Lissy93/portainer-templates, a community collection of several hundred apps, includes aimm:
- In Settings › App Templates, set URL to
https://raw.githubusercontent.com/Lissy93/portainer-templates/main/templates.jsonand save. This replaces Portainer's default list. - In App Templates, choose AI Marketplace Monitor. Fill in the Facebook username and password, replace the placeholder UnitySVC API key with yours, and set the time zone. Web UI sign-in chooses whether aimm asks for the Facebook login (the default) or a web UI password of its own (
local), or leaves the sign-in to your reverse proxy (see Who signs you in to the web UI below). - Deploy the container, then open
http://<host>:8467and continue with First run below. The config, cache and logs are in a named volume mounted at/data.
To list only aimm instead, use https://raw.githubusercontent.com/BoPeng/ai-marketplace-monitor/main/deploy/portainer/templates.json as the URL. Portainer shows the form's passwords as plain text fields; its template format cannot mask them.
To update, open the container, choose Recreate and turn on Re-pull image; the volume keeps your data.
First run
On first start, aimm creates config.toml in the mounted directory (data/config.toml with Docker Compose) unless one is there already. The default configuration:
- logs in to Facebook with
FACEBOOK_USERNAMEandFACEBOOK_PASSWORD, and searches around Houston (search_city) - rates listings with UnitySVC AI (
[ai.unitysvc], modelbalanced, which also reads listing photos) - sends each match as an email with photos (
[notification.unitysvc_email]) to the address registered with UnitySVC, and as a short message ([notification.unitysvc]) to your UnitySVC inbox and the destination you saved in UnitySVC (Discord, Slack, SMS, phone push, ...) - sends a daily digest at 08:00 (
digest_at) - searches for an example item,
[item.example]
The settings that hold secrets name environment variables, such as api_key = "${UNITYSVC_API_KEY}", so the file contains no passwords.
Then:
- Open http://localhost:8467 (or
http://<server>:8467) and sign in with your Facebook username and password, the values ofFACEBOOK_USERNAMEandFACEBOOK_PASSWORD. Because Docker exposes the web UI on the network, aimm requires these credentials for the web UI and for its browser view. - Change
search_cityand replace[item.example]with what you are looking for. Edit them in the web UI's editor, or have the Configure chat set them up for you. aimm picks up a saved change on its own; there is no need to restart it. - aimm types your Facebook username and password into its browser. If Facebook asks for a CAPTCHA or a security code, a banner appears in the web UI: click Open browser and complete the check there. Searches start once you are logged in.
- To check your notifications, use Send test in Settings, or run
docker compose exec aimm aimm admin --test-notification.
Behind a reverse proxy
To reach aimm over HTTPS, put it behind a reverse proxy so that port 8467 is reachable only through the proxy. The proxy must pass WebSocket connections, which the log stream and the browser view use. For Traefik on a Docker network named proxy, download docker-compose.traefik.yml as docker-compose.override.yml, which Docker Compose merges into docker-compose.yml by itself, and set AIMM_DOMAIN in .env:
curl -fsSL -o docker-compose.override.yml https://raw.githubusercontent.com/BoPeng/ai-marketplace-monitor/main/docker-compose/docker-compose.traefik.yml
echo "AIMM_DOMAIN='aimm.example.com'" >> .env
docker compose up -d
The override removes the published port and adds the Traefik labels. Change its entrypoint (websecure) and certificate resolver (letsencrypt) to the names your Traefik uses. It needs Docker Compose 2.24 or later.
Anyone who can reach the URL sees the aimm sign-in page, which is protected only by your Facebook credentials. You can also put the site behind your proxy's own authentication (for example a forward-auth middleware).
Who signs you in to the web UI
AIMM_WEBUI_AUTH, in .env (or with -e for docker run), chooses who signs you in to the web UI:
facebook(the default;passwordis its old name): aimm asks for the Facebook username and password, the same ones it logs in to Facebook with.local: aimm asks for a username and password of the web UI's own,AIMM_WEBUI_USERNAME(adminby default) andAIMM_WEBUI_PASSWORD, whatever the Facebook credentials are. aimm refuses to start withoutAIMM_WEBUI_PASSWORD. The web UI starts even before you have set the Facebook credentials, which you can then enter in its config editor. App platforms use this to show a password they generate.- A reverse proxy that signs users in, as below.
Let the reverse proxy sign you in
If your reverse proxy already signs users in, aimm does not need to ask for a password as well. Set AIMM_WEBUI_AUTH to the proxy that signs you in. aimm then checks, on every request, what that proxy adds once you are signed in, so a request that goes around the proxy is refused:
AIMM_WEBUI_AUTH |
Each request must carry | Settings |
|---|---|---|
facebook (default) |
aimm's own sign-in, with the Facebook username and password | |
local |
aimm's own sign-in, with the web UI's own username and password | AIMM_WEBUI_PASSWORD (required) and AIMM_WEBUI_USERNAME (admin by default) |
authentik |
the signed token in X-Authentik-Jwt from Authentik's proxy outpost, issued for aimm's application |
AIMM_WEBUI_JWKS_URL: the provider's JWKS URL, e.g. https://auth.example.com/application/o/aimm/jwks/. AIMM_WEBUI_JWT_AUDIENCE: the provider's client ID. The issuer is taken from the JWKS URL (https://auth.example.com/application/o/aimm/); set AIMM_WEBUI_JWT_ISSUER if your URL has another form |
cloudflare |
the signed token in Cf-Access-Jwt-Assertion from Cloudflare Access |
AIMM_WEBUI_CF_TEAM: your team name (<team>.cloudflareaccess.com). AIMM_WEBUI_JWT_AUDIENCE: the application's AUD tag |
authelia |
the Remote-User header from Authelia's forward auth |
Optional AIMM_WEBUI_USER_HEADER for another header, e.g. the one a basic-auth middleware sets |
proxy |
nothing |
authentik and cloudflare verify a token that the identity provider signs, and that it was issued for aimm (its audience and issuer), so a forged request, or a token for another application, is refused even if it reaches aimm's port directly. When the token expires, aimm also ends the web UI's open connections: the log reconnects by itself with the proxy's new token, and you reopen the browser view or start the Configure chat again. authelia and proxy cannot tell your proxy from anyone else who reaches the port. For them, also set AIMM_WEBUI_PROXY_SECRET to a long random value (for example from openssl rand -hex 32), and have the proxy add it to every request as the X-Aimm-Proxy-Secret header, for example with Traefik's headers middleware (customRequestHeaders), nginx's proxy_set_header or Caddy's header_up. Without the secret, aimm logs a warning, and you must make sure that port 8467 is reachable only through the proxy: anyone who reaches it directly controls aimm and sees its browser, which is logged in to your Facebook account.
aimm still logs in to Facebook with FACEBOOK_USERNAME and FACEBOOK_PASSWORD, so keep them set. The web UI keeps protecting itself against requests from other websites, so a page you visit cannot use your proxy sign-in to change aimm's settings. Settings shows who the proxy signed in.
CasaOS signs you in to its dashboard, not to the apps, which are published on the host's ports. Keep facebook there, or use local for a web UI password of its own.
Update
When a new release is out, the web UI header shows ⬆ aimm X available, which opens Settings with an Update button. It installs the release inside the running container and restarts aimm; the page reloads when it is back. The update lives in the container: it survives a restart, but recreating the container from an older image brings back the old version, and the button offers the update again. The button is there only when aimm runs as the image's own user, ID 1000; with another PUID, or --user, update the image instead.
To update the image itself, pull it and recreate the container. Restarting the container keeps running the old image. With Docker Compose:
docker compose pull
docker compose up -d
With docker run:
docker pull ghcr.io/bopeng/ai-marketplace-monitor:latest
docker rm -f aimm
and run the docker run command again. Your config, cache and logs are kept in the mounted directory. The web UI header shows the running version, as does docker exec aimm aimm --version.
Troubleshooting
- The web UI says the credentials are wrong: sign in with the values of
FACEBOOK_USERNAMEandFACEBOOK_PASSWORD. Check that the container received them withdocker compose exec aimm printenv FACEBOOK_USERNAME. If you changed.env, rundocker compose up -dto recreate the container;docker compose restartkeeps the old environment. - "Environment variable ... is not set" or "UnitySVC requires a string api_key": a
${VAR}inconfig.tomlnames a variable that is not in the container's environment. With Docker Compose, add it to.env, then rundocker compose up -d; withdocker run, pass it with-e. - The web UI does not load: check the log with
docker compose logs aimm(ordocker logs aimm). - More or less detail in the log: set
AIMM_LOG_LEVELin.env(or with-efordocker run) toDEBUG,INFO(the default),WARNINGorERROR, then rundocker compose up -d. It sets what the container log and the web UI's Logs tab show;ai-marketplace-monitor.login the data folder always records everything. - The container shows as
unhealthy: the web UI does not answer. See the log; the image checkshttp://127.0.0.1:8467/api/healthinside the container every 30 seconds. - "cannot write the data folder /data": the container was started as a user (
user:) that does not own the mounted folder. Give it to that user (sudo chown -R <uid>:<gid> data), or removeuser:and setPUIDandPGIDinstead. - With
cap_drop: ALL(a hardened setup), addcap_add: [SETUID, SETGID]so that the container can switch to theaimmuser, or start it as a fixed user withuser:. WithoutCHOWN, aimm cannot change the owner of files in the data folder; it still starts if it can write them, and otherwise asks you to fix their permissions on the host. The same applies to NFS shares withroot_squashand to SMB shares. - Run aimm commands in the container, for example
docker compose exec aimm aimm check <listing>, not with an aimm installed on the host. aimm's cache is an SQLite database, and the two would write it through the mounted directory at the same time and could damage it. If aimm stops with "cannot be read", rundocker compose exec aimm aimm admin --clear-cache alland restart the container.
Requirements
Categories
Download Statistics
Related apps
Explore more like this
Explore allDetails
ghcr.io/bopeng/ai-marketplace-monitor:latestRuntime arguments
- Web UI
http://[IP]:[PORT:8467]/- Network
bridge- Shell
sh- Privileged
- false
Template configuration
Port of the web UI.
- Target
- 8467
- Default
- 8467
- Value
- 8467
config.toml, the cache and the logs.
- Target
- /data
- Default
- /mnt/user/appdata/ai-marketplace-monitor
- Value
- /mnt/user/appdata/ai-marketplace-monitor
The Facebook account aimm logs in with. Also signs you in to the web UI.
- Target
- FACEBOOK_USERNAME
Password of that Facebook account. Also signs you in to the web UI.
- Target
- FACEBOOK_PASSWORD
For the default configuration: the AI that rates listings, and email and phone notifications. Sign up at https://unitysvc.com and create an API key. Replace the placeholder with your key; with the placeholder, aimm searches but cannot rate listings or send notifications until you set a key here or other AI and notification services in the web UI.
- Target
- UNITYSVC_API_KEY
- Default
- svcpass_XXXXX
- Value
- svcpass_XXXXX
facebook: sign in with the Facebook username and password. local: sign in with the web UI username and password below. Behind a reverse proxy that signs users in, choose it and set its variables (see the Docker installation guide).
- Target
- AIMM_WEBUI_AUTH
- Default
- facebook|local|authelia|authentik|cloudflare|proxy
- Value
With Web UI sign-in local: the username of the web UI.
- Target
- AIMM_WEBUI_USERNAME
- Default
- admin
- Value
- admin
With Web UI sign-in local (required): the password of the web UI, unrelated to the Facebook password.
- Target
- AIMM_WEBUI_PASSWORD
User ID that owns the files in the data folder.
- Default
- 99
- Value
- 99
Group ID that owns the files in the data folder.
- Default
- 100
- Value
- 100