# Oracle Always Free Docker Deployment ## 1. Create VM - Use Ubuntu Always Free. - Prefer Ampere A1 if available. - Keep boot/block volume within Always Free limits. ## 2. Keep the VM private first - Do not open `80/tcp`, `443/tcp`, or public DNS yet. - Restrict `22/tcp` to your IP. - The initial account is `admin` / `admin`; change it before the panel is reachable from the internet. ## 3. Install Docker ```bash sudo apt-get update sudo apt-get install -y ca-certificates curl gnupg curl -fsSL https://get.docker.com | sh sudo usermod -aG docker $USER ``` ## 4. Configure app ```bash cp .env.production.example .env.production nano .env.production cp Caddyfile.example Caddyfile nano Caddyfile ``` For Telegram alerts: - Create a bot with BotFather and copy the bot token into `TELEGRAM_BOT_TOKEN`. - Send a message to the bot from the operator account or group. - Get the destination `TELEGRAM_CHAT_ID` from the Telegram API or your preferred bot admin tool. - Keep `TELEGRAM_ALERTS_ENABLED=true` only when both values are configured. - To disable alerts safely, set `TELEGRAM_ALERTS_ENABLED=false` and leave token/chat fields blank. - Never commit `.env.production` or share bot tokens, chat IDs, databases, logs, or WhatsApp auth data. ## 5. First startup on SSH-only access - Keep OCI ingress for `80/tcp` and `443/tcp` closed for this first run. - Do not start Caddy yet. Start only the app with a temporary localhost-only host port: ```bash cat > docker-compose.local-first.yml <<'YAML' services: app: ports: - "127.0.0.1:3910:3910" YAML docker compose -f docker-compose.yml -f docker-compose.local-first.yml up -d --build app docker compose ps docker compose logs -f app ``` From your workstation, create an SSH tunnel and change the default password before exposing the stack: ```bash ssh -L 3910:127.0.0.1:3910 ubuntu@YOUR_VM_PUBLIC_IP ``` - Open `http://127.0.0.1:3910` through the tunnel. - Log in with `admin` / `admin`. - Open **Configuracoes > Alterar minha senha** and set a strong unique password with at least 8 characters. - Log out and log back in with the new password. ## 6. Expose HTTPS after password change - Only after the admin password is changed, update `Caddyfile` to the public domain and point public DNS at the VM. - Remove the temporary local-only override and start the public stack: ```bash rm docker-compose.local-first.yml docker compose up -d --build ``` - Only after the public stack is ready, open OCI ingress for `80/tcp` and `443/tcp` from the internet. ## 7. Smoke test safely - Keep campaigns paused during deployment validation. - Do not start real campaigns during smoke tests. - Keep Google Places and Telegram tokens blank or fake unless intentionally testing those external services. - Do not connect a real WhatsApp account or send real WhatsApp messages during smoke tests. - Confirm health without sending: ```bash curl -i http://127.0.0.1/api/health docker compose restart app docker compose ps docker compose logs --tail=100 app ``` Expected: health is 200, the app container is healthy after restart, data remains in `/app/data`, and no outreach sends are created. ## 8. Backup ```bash docker compose exec app npm run backup:data ``` ## 9. QR recovery When Telegram says QR is required, open the panel and reconnect WhatsApp.