Skip to content

Latest commit

 

History

History
359 lines (235 loc) · 7.74 KB

File metadata and controls

359 lines (235 loc) · 7.74 KB

Slef Hosting guide

Here’s a full end-to-end “how do I self-host this thing with docker-compose” walkthrough.

I’ll assume:

  • You’re running on a Linux server (Ubuntu/Debian style) with shell access.

  • Your stack is:

    • core (Express/TypeScript API)([GitHub][1])
    • console (Next.js frontend)([GitHub][2])
    • mongo (database)
  • Your docker-compose.yml lives at https://github.com/Senzops/.github/blob/dev/docker-compose.yml and wires those three together.


1. Install Docker & Docker Compose

On a fresh Ubuntu/Debian server (run as a sudo user):

# Update packages
sudo apt-get update

# Install Docker
sudo apt-get install -y ca-certificates curl gnupg

# Official Docker repo (simplified from Docker docs)
curl -fsSL https://get.docker.com | sudo sh

# Enable & start Docker
sudo systemctl enable docker
sudo systemctl start docker

Docker Compose v2 is now built into docker as docker compose.([Docker Documentation][3])

Check:

docker --version
docker compose version

2. Prepare a folder for the stack

Pick a root folder where the whole stack will live:

mkdir -p ~/senzor-stack
cd ~/senzor-stack

Your final structure will look like:

senzor-stack/
  core/
  console/
  docker-compose.yml
  .env            # optional, for secrets

3. Clone the application repos

From inside ~/senzor-stack:

git clone https://github.com/Senzops/core.git
git clone https://github.com/Senzops/console.git

You should now have core/ and console/ in this directory.


4. Fetch the docker-compose.yml

Still from ~/senzor-stack, you have two options:

Option A – Copy via browser (easiest)

  1. Open https://github.com/Senzops/.github/blob/dev/docker-compose.yml in your browser.

  2. Click Raw.

  3. Copy all contents.

  4. On your server:

    nano docker-compose.yml

    Paste the contents and save.

Option B – Directly download (if you prefer CLI)

From your server, something like:

curl -L "https://raw.githubusercontent.com/Senzops/.github/dev/docker-compose.yml" -o docker-compose.yml

If that exact raw URL ever differs, just grab whatever GitHub shows on the Raw view.


5. Create a .env file for secrets (recommended)

If your docker-compose.yml uses placeholders or references environment variables for Firebase / Mongo passwords, add them to a .env file next to docker-compose.yml:

cd ~/senzor-stack
nano .env

Example content (adjust to match your compose file):

# --- Mongo credentials (example) ---
MONGO_ROOT_USER=senzore_root
MONGO_ROOT_PASSWORD=some-long-random-password

# --- Core service ---
FIREBASE_SERVICE_ACCOUNT='{"type":"service_account","project_id":"...","private_key":"-----BEGIN PRIVATE KEY-----\n..."}'
## Demo User (firebaseUid)
## OPTIONAL: Add when demo access required
DEMO_USER_ID=senzor-demo-account

# --- Console (Next.js) ---
NEXT_PUBLIC_API_URL=http://localhost:5000/api

NEXT_PUBLIC_FIREBASE_API_KEY=your-firebase-api-key
NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN=your-project.firebaseapp.com
NEXT_PUBLIC_FIREBASE_PROJECT_ID=your-project-id

Then, in docker-compose.yml, it will either:

  • Directly read from .env automatically (compose does this by default), or
  • Use ${VAR_NAME} in the environment: blocks, like:
services:
  core:
    environment:
      MONGO_URI: "mongodb://$MONGO_ROOT_USER:$MONGO_ROOT_PASSWORD@mongo:27017/senzore?authSource=admin"
      FIREBASE_SERVICE_ACCOUNT: "${FIREBASE_SERVICE_ACCOUNT}"
      DEMO_USER_ID: "${DEMO_USER_ID}"

  console:
    environment:
      NEXT_PUBLIC_API_URL: "${NEXT_PUBLIC_API_URL}"
      NEXT_PUBLIC_FIREBASE_API_KEY: "${NEXT_PUBLIC_FIREBASE_API_KEY}"
      NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN: "${NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN}"
      NEXT_PUBLIC_FIREBASE_PROJECT_ID: "${NEXT_PUBLIC_FIREBASE_PROJECT_ID}"

Important: Make sure .env is never committed to Git.


6. Confirm Dockerfiles exist and match compose

You should already have Dockerfiles in:

  • core/Dockerfile – builds the Express API (TypeScript → dist → npm start)
  • console/Dockerfile – builds Next.js production app (npm run buildnpm start)

From ~/senzor-stack:

ls core
ls console

You should see Dockerfile in both.

If your compose file references them like:

core:
  build:
    context: ./core

console:
  build:
    context: ./console

…you’re good.


7. (Optional but recommended) Adjust ports / domains

By default, likely:

  • Mongo: internal name mongo and maybe exposed as 27017 on the host
  • Core: exposed on host as 5000
  • Console: exposed on host as 3000

In docker-compose.yml, check for:

core:
  ports:
    - "5000:5000"

console:
  ports:
    - "3000:3000"

If you’re putting this behind a reverse proxy (Traefik, Nginx, Caddy), you might:

  • Stop exposing ports publicly.
  • Instead, expose only via the proxy network.

For first self-hosting, keeping these as-is is fine. You’ll then reach:

  • Backend: http://<server-ip>:5000
  • Frontend: http://<server-ip>:3000

8. Build the images

From ~/senzor-stack:

docker compose build

This will:

  • Build the core image using its Dockerfile.
  • Build the console image using its Dockerfile.
  • Pull the mongo image from Docker Hub.

Fix any build issues (missing env, wrong paths) before continuing.


9. Start the stack

Once build succeeds:

docker compose up -d

This will:

  • Start MongoDB first.
  • Start core (pointing at the Mongo URI from env / compose).
  • Start console (pointing at core via NEXT_PUBLIC_API_URL=http://localhost:5000/api).

Check status:

docker compose ps

You should see all three services marked as Up.


10. Check logs

If something doesn’t behave:

# See everything
docker compose logs -f

# See only core logs
docker compose logs -f core

# Only console
docker compose logs -f console

# Only mongo
docker compose logs -f mongo

Common things to confirm:

  • Mongo: no auth errors (wrong username/password / authSource).
  • Core: successfully connects to Mongo (no connection/refused).
  • Console: successfully reaches http://core:5000 internally and NEXT_PUBLIC_API_URL is set correctly for browser calls (should be http://<public-host>:5000/api in production).

11. Test from your browser

From your laptop / local machine:

  1. Get the server’s IP or domain (e.g. 203.0.113.10 or monitoring.example.com).

  2. Open:

    http://<server-ip>:3000
    
  3. The Senzor Console UI should appear.

  4. When you log in via Firebase and hit dashboard pages, they will call backend at:

    NEXT_PUBLIC_API_URL (e.g. http://<server-ip>:5000/api)
    

Make sure you configured Firebase Auth correctly in your env variables (matching what’s in the console README).([GitHub][2])


12. Securing in production (high-level checklist)

Once it works:

  • Use strong Mongo credentials (long random password in .env).

  • Don’t expose Mongo externally unless absolutely required:

    • Either remove ports: "27017:27017" from Mongo in compose, or firewall it.
  • Use HTTPS:

    • Put Nginx / Traefik / Caddy in front of console and core.
    • Terminate TLS there and proxy to containers over the internal Docker network.
  • Lock down the server:

    • Use UFW / security groups.
    • Only allow 80/443 (and maybe 22 for SSH).

13. Updating to a new version

When you push new commits to core or console:

cd ~/senzor-stack

# Pull latest code
cd core && git pull && cd ..
cd console && git pull && cd ..

# Rebuild + restart
docker compose build
docker compose up -d

Docker will recreate containers with the new images while keeping volumes (e.g. MongoDB data).