# Deploy PostSync Pro — postsyncpro.gventure.info

Apache terminates SSL and **proxies all traffic** to Next.js on a **port you choose** (e.g. `3033`).  
The app is **not** served as static files from `DocumentRoot` — Node must be running.

---

## Port — one value in two places

Pick a free port on the server (check with `ss -tlnp | grep 3033`). Use the **same number** in:

| Place | Setting |
|-------|---------|
| **Server** `.env.local` | `PORT=3033` |
| **Apache** SSL `.conf` | `ProxyPass "/" "http://127.0.0.1:3033/"` |

The Next.js app reads `PORT` from `.env.local` automatically (`npm run start`).  
PM2 does **not** hardcode a port — see `ecosystem.config.cjs`.

Example Apache templates: `docs/apache/*.conf.example`

---

## Architecture

```
Browser → Apache :443 (SSL) → ProxyPass → Node/Next.js :YOUR_PORT
```

Your SSL vhost is correct in principle. HTTP (:80) redirects to HTTPS.

---

## 1. Server prerequisites

SSH to the server (`192.187.106.194`):

```bash
# Node.js 20+ (example with nvm)
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash
source ~/.bashrc
nvm install 20
nvm use 20

# PM2 (keeps Next.js running after logout)
npm install -g pm2

# Apache proxy modules (Debian/Ubuntu)
sudo a2enmod proxy proxy_http headers rewrite ssl
sudo systemctl reload apache2
```

On **CentOS/RHEL** (httpd instead of apache2):

```bash
sudo yum install httpd mod_ssl
# Enable in /etc/httpd/conf.modules.d/ — proxy, proxy_http, headers
sudo systemctl enable --now httpd
```

---

## 2. Upload the project

Deploy code to the path Apache/PM2 expect:

```bash
sudo mkdir -p /var/www/html/gventure
sudo chown -R $USER:$USER /var/www/html/gventure

# Option A: git clone
cd /var/www/html/gventure
git clone <your-repo-url> postsync_pro

# Option B: rsync from your PC (run on Windows with WSL or use WinSCP)
# rsync -avz --exclude node_modules --exclude .next ./ postsync_pro/ user@192.187.106.194:/var/www/html/gventure/postsync_pro/
```

---

## 3. Environment file on server

```bash
cd /var/www/html/gventure/postsync_pro
cp .env.production.example .env.local
nano .env.local   # fill in API keys and LinkedIn credentials
```

**Required for production:**

| Variable | Value |
|----------|--------|
| `NEXT_PUBLIC_APP_URL` | `https://postsyncpro.gventure.info` |
| `PORT` | Your chosen port (e.g. `3033`) — **same as Apache ProxyPass** |
| `LINKEDIN_CLIENT_ID` | From [LinkedIn Developer Portal](https://www.linkedin.com/developers/) — **not** the placeholder `your_linkedin_client_id` |
| `LINKEDIN_CLIENT_SECRET` | App secret from the same LinkedIn app |
| `LINKEDIN_SOCIAL_REDIRECT_URI` | `https://postsyncpro.gventure.info/connected-accounts/oauth/linkedin/callback` |
| `LINKEDIN_SCOPES` | `w_member_social` (posting scope) |

In [LinkedIn Developer Portal](https://www.linkedin.com/developers/) → your app → **Auth** → **Authorized redirect URLs**, add **exactly**:

`https://postsyncpro.gventure.info/connected-accounts/oauth/linkedin/callback`

After changing `.env.local`, restart Node so env vars reload:

```bash
pm2 restart postsync-pro
```

---

## 4. Build and start

```bash
cd /var/www/html/gventure/postsync_pro
npm ci
npm run build
pm2 start ecosystem.config.cjs
pm2 save
pm2 startup   # run the command it prints so PM2 starts on boot
```

Verify Node is listening:

```bash
curl -I http://127.0.0.1:3033/
# Expect HTTP/1.1 307 or 200
```

---

## 5. Apache SSL vhost (recommended tweaks)

File: `/etc/apache2/sites-available/postsyncpro.gventure.info-le-ssl.conf`

Add **inside** `<VirtualHost *:443>`, before or after `ProxyPass`:

```apache
    RequestHeader set X-Forwarded-Proto "https"
    RequestHeader set X-Forwarded-Host "postsyncpro.gventure.info"
    RequestHeader set X-Forwarded-Port "443"

    ProxyPreserveHost On
    ProxyRequests Off
    ProxyPass "/" "http://127.0.0.1:3033/"
    ProxyPassReverse "/" "http://127.0.0.1:3033/"
```

Enable site and reload:

```bash
sudo a2ensite postsyncpro.gventure.info postsyncpro.gventure.info-le-ssl
sudo apache2ctl configtest
sudo systemctl reload apache2
```

---

## 6. Writable data directory

Generated posts are stored in `data/generated-posts.json`.  
Per-user project workspaces are stored in `data/users/{userId}/projects.json` (synced from the browser after login).

```bash
mkdir -p /var/www/html/gventure/postsync_pro/data
chmod 775 /var/www/html/gventure/postsync_pro/data
# If PM2 runs as a different user, chown accordingly
```

---

## 7. DNS

Ensure DNS A record points to the server:

```
postsyncpro.gventure.info  →  192.187.106.194
```

---

## 8. Firewall

```bash
# Allow HTTP/HTTPS (ufw example)
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
# Do NOT expose 3033 publicly — only localhost
```

---

## 9. Deploy updates (after code changes)

```bash
cd /var/www/html/gventure/postsync_pro
git pull          # or upload new files
npm ci
npm run build
pm2 restart postsync-pro
```

If build cache is corrupt:

```bash
npm run clean
npm run build
pm2 restart postsync-pro
```

---

## 10. Troubleshooting

| Symptom | Fix |
|---------|-----|
| 502 Bad Gateway | Next.js not running — `pm2 status`, `pm2 logs postsync-pro` |
| 503 / timeout | Check `curl http://127.0.0.1:3033/` on server |
| Site shows directory listing | SSL vhost not enabled or ProxyPass missing — Apache serving DocumentRoot instead of proxy |
| LinkedIn connect fails | `LINKEDIN_CLIENT_ID` must be real (not placeholder); add `LINKEDIN_SOCIAL_REDIRECT_URI` in `.env.local`; register same URL in LinkedIn app; `pm2 restart postsync-pro` |
| Cookies not set | Must use HTTPS in production (`secure` cookies) |
| Empty generated posts | Check `data/` folder permissions |

**Logs:**

```bash
pm2 logs postsync-pro
sudo tail -f /var/log/apache2/postsyncpro.gventure.info.log
```

---

## Quick checklist

- [ ] Node 20+ installed
- [ ] Code in `/var/www/html/gventure/postsync_pro`
- [ ] `.env.local` with production URL and keys
- [ ] `npm run build` succeeds
- [ ] PM2 running on port **3033**
- [ ] `curl http://127.0.0.1:3033/` works on server
- [ ] Apache SSL vhost proxies to 3033
- [ ] DNS → `192.187.106.194`
- [ ] https://postsyncpro.gventure.info loads login page
