- multi-stage Dockerfile; worker bundled to build/worker.mjs (no tsx at runtime) - docker-compose.yml + docker-compose.nginx.yml (127.0.0.1:3320), Nginx site, encrypted backups - production URLs (datewise.metatronlabz.com) in shopify.app.toml; URL auto-update off - verified locally: healthz/landing/privacy/terms 200, unsigned proxy/webhook 400, worker starts Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
70 lines
3.1 KiB
Markdown
70 lines
3.1 KiB
Markdown
# Deploying Datewise to the VPS
|
|
|
|
Domain: **https://datewise.metatronlabz.com** · Server path: `/opt/datewise` · App port (Nginx variant): `127.0.0.1:3320`
|
|
|
|
The stack is Postgres + the web app + the worker (one image, two containers). The Shopify extensions and functions are released separately from your PC with `shopify app deploy`.
|
|
|
|
## 1. DNS
|
|
Create an **A record**: `datewise.metatronlabz.com` → the VPS IP. Check with `dig +short datewise.metatronlabz.com`.
|
|
|
|
## 2. Get the code on the server
|
|
```sh
|
|
mkdir -p /opt && cd /opt
|
|
git clone <datewise repo url> datewise && cd datewise
|
|
```
|
|
|
|
## 3. Secrets (on the server only, never in Git or chat)
|
|
```sh
|
|
cp .env.example .env
|
|
openssl rand -hex 24 # → POSTGRES_PASSWORD
|
|
openssl rand -base64 32 # → APP_ENCRYPTION_KEY (store it in the password manager too; never change it)
|
|
nano .env # fill APP_DOMAIN, SHOPIFY_API_KEY, SHOPIFY_API_SECRET, the two values above,
|
|
# and optionally GOOGLE_MAPS_API_KEY, RESEND_API_KEY, EMAIL_FROM_DOMAIN
|
|
chmod 600 .env
|
|
```
|
|
`SHOPIFY_API_KEY` is the client ID; copy `SHOPIFY_API_SECRET` straight from the Dev Dashboard into `.env`.
|
|
|
|
## 4a. Start: the VPS already runs Nginx (same server as Offerlyst)
|
|
```sh
|
|
ss -ltnp | grep 3320 || echo "3320 free" # pick another port in docker-compose.nginx.yml + the Nginx conf if taken
|
|
docker compose -f docker-compose.yml -f docker-compose.nginx.yml up -d --build db app worker
|
|
cp deploy/nginx-datewise.conf /etc/nginx/sites-available/datewise.metatronlabz.com
|
|
ln -s /etc/nginx/sites-available/datewise.metatronlabz.com /etc/nginx/sites-enabled/
|
|
nginx -t && systemctl reload nginx
|
|
certbot --nginx -d datewise.metatronlabz.com
|
|
```
|
|
|
|
## 4b. Start: a fresh VPS with nothing on 80/443
|
|
```sh
|
|
docker compose up -d --build # Caddy gets the HTTPS certificate automatically
|
|
```
|
|
|
|
## 5. Check it from outside
|
|
```sh
|
|
docker compose ps # db, app healthy; worker up
|
|
docker compose logs -f app worker # worker prints "[worker] started"
|
|
curl -s -o /dev/null -w '%{http_code}\n' https://datewise.metatronlabz.com/healthz # 200
|
|
curl -s -o /dev/null -w '%{http_code}\n' https://datewise.metatronlabz.com/privacy # 200
|
|
curl -s -o /dev/null -w '%{http_code}\n' https://datewise.metatronlabz.com/terms # 200
|
|
curl -s -o /dev/null -w '%{http_code}\n' -X POST https://datewise.metatronlabz.com/webhooks/app # 400/401 (unsigned)
|
|
curl -s https://datewise.metatronlabz.com/ | grep -c 'name="shop"' # 0 (no shop-domain form)
|
|
```
|
|
|
|
## 6. Release the Shopify side (from your PC, in `datewise/`)
|
|
```sh
|
|
shopify app deploy
|
|
```
|
|
|
|
## 7. Backups (once)
|
|
```sh
|
|
openssl rand -hex 32 > /root/.datewise-backup-key && chmod 600 /root/.datewise-backup-key
|
|
chmod +x /opt/datewise/scripts/backup.sh
|
|
( crontab -l; echo "0 3 * * * /opt/datewise/scripts/backup.sh >> /var/log/datewise-backup.log 2>&1" ) | crontab -
|
|
```
|
|
|
|
## Redeploy after every push
|
|
```sh
|
|
cd /opt/datewise && git pull && docker compose -f docker-compose.yml -f docker-compose.nginx.yml up -d --build app worker
|
|
```
|
|
Then confirm the change is live with `curl`.
|