Driftsättning - jakobher/mindtracker GitHub Wiki

Driftsättning av MindTracker med Docker Compose

Detta dokument beskriver processen för att driftsätta MindTracker-applikationen med Docker Compose på DigitalOcean:s servermiljö. Driftsättningen använder Docker-containrar för Node.js, MongoDB och NGINX med HTTPS-stöd via Let's Encrypt.

Förutsättningar

  • Servermiljö: Ubuntu-server på DigitalOcean:s molnplattform
  • Domännamn: mindtracker.se
  • IP-adress: 194.47.177.236
  • Öppna portar: 22, 80, 443

1. Serverförberedelser

Först anslöt vi till servern och uppdaterade systemet:

ssh [email protected]

sudo apt update
sudo apt upgrade -y

sudo apt install -y curl wget git build-essential

2. Installera Docker & Docker Compose

Docker och Docker Compose installerades för att hantera containrarna:

sudo apt install -y docker.io

sudo usermod -aG docker $USER

sudo apt install -y docker-compose

docker --version
docker-compose --version

3. Konfigurera SSH-nyckel för GitLab

För att kunna hämta kod från GitLab behövde vi konfigurera SSH-nycklar:

mkdir -p ~/.ssh
chmod 700 ~/.ssh
ssh-keygen -t ed25519 -C "mindtracker-server@digitalocean"

cat ~/.ssh/id_ed25519.pub

Den offentliga nyckeln lades sedan till i GitLab-kontot under SSH Keys.

4. Klona projektrepository

Efter att SSH-nyckeln konfigurerats, klonade vi projektet:

cd ~
git clone [email protected]:jakobher/mindtracker.git mindtracker
cd mindtracker

git checkout feature/docker-deployment

5. Skapa Docker-konfigurationsfiler

Vi skapade följande filer för Docker-driftsättningen:

Dockerfile

FROM node:18-alpine

WORKDIR /usr/src/app

# Kopiera package.json och package-lock.json först för att utnyttja Docker-cache
COPY package*.json ./

# Installera beroenden
RUN npm ci --only=production

# Kopiera resten av applikationen
COPY . .

# Exponera port
EXPOSE 3000

# Kör applikationen
CMD ["node", "src/server.js"]

docker-compose.yml

version: '3.8'

services:
  # NGINX reverse proxy
  nginx:
    image: nginx:alpine
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/conf.d/default.conf
      - /etc/letsencrypt:/etc/letsencrypt
    depends_on:
      - app
    networks:
      - mindtracker-network

  # Node.js-applikation
  app:
    build: .
    restart: unless-stopped
    env_file: .env
    depends_on:
      - mongo
    networks:
      - mindtracker-network
    environment:
      - NODE_ENV=production
      - PORT=3000
      - DB_CONNECTION_STRING=mongodb://mongo:27017/mindtracker
      - SESSION_NAME=mindtracker_session
      - SESSION_SECRET=${SESSION_SECRET:-din_hemliga_nyckel_här}
      - BASE_URL=/

  # MongoDB
  mongo:
    image: mongo:5.0
    restart: unless-stopped
    volumes:
      - mongo-data:/data/db
    networks:
      - mindtracker-network

networks:
  mindtracker-network:
    driver: bridge

volumes:
  mongo-data:

.env-fil

Vi skapade en miljövariabler-fil från mallen:

PORT=3000
DB_CONNECTION_STRING=mongodb://mongo:27017/mindtracker
NODE_ENV=production
SESSION_NAME=mindtracker_session
SESSION_SECRET=a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0
BASE_URL=/

6. Konfigurera HTTPS med Let's Encrypt

En nyckelfaktor var att installera och konfigurera Let's Encrypt för HTTPS:

sudo apt install -y certbot python3-certbot-nginx

sudo systemctl stop nginx
sudo systemctl disable nginx

sudo certbot --nginx -d mindtracker.se

Certbot konfigurerade NGINX automatiskt för att använda SSL-certifikaten.

7. Skapa NGINX-konfiguration

Vi skapade en NGINX-konfigurationsfil för att hantera både HTTP och HTTPS:

server {
    listen 80;
    server_name mindtracker.se;
    return 301 https://$host$request_uri;  # Omdirigera HTTP till HTTPS
}

server {
    listen 443 ssl;
    server_name mindtracker.se;

    ssl_certificate /etc/letsencrypt/live/mindtracker.se/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/mindtracker.se/privkey.pem;
    ssl_protocols TLSv1.2 TLSv1.3;

    location / {
        proxy_pass http://app:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_cache_bypass $http_upgrade;
    }

    # Lägg till caching för statiska filer
    location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
        proxy_pass http://app:3000;
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
        expires 30d;
        add_header Cache-Control "public, no-transform";
    }
}

8. Driftsätta applikationen

När alla konfigurationer var klara, startade vi Docker Compose:

docker-compose up -d --build

docker-compose ps

Vi mötte initialt ett problem där app-containern försökte starta om upprepade gånger på grund av att controller-filen hade ett annat namn än vad routern förväntade sig. Detta löstes genom att skapa rätt filnamn.

9. Säkerställa portkonflikter

En viktig del av processen var att hantera potentiella portkonflikter:

sudo systemctl stop nginx
sudo systemctl disable nginx

sudo ufw allow 80/tcp
sudo ufw allow 443/tcp

10. Verifiera driftsättningen

Slutligen verifierade vi att applikationen fungerade:

  1. Öppnade https://mindtracker.se i en webbläsare
  2. Kontrollerade att HTTPS-omdirigering fungerade
  3. Testade att loginflödet fungerade

Nyckelinsikter från driftsättningen

  1. HTTPS-konfiguration var avgörande - Det var viktigt att konfigurera NGINX för både port 80 och 443, med korrekt omdirigering.
  2. Let's Encrypt-integration - För att integrera Let's Encrypt-certifikat med Docker behövde vi montera certifikatmappen i NGINX-containern.
  3. Filnamnskänslighet i Linux - Linux är skiftlägeskänsligt, vilket orsakade ett initialt problem med controllers-filen (ExposureController.js vs exposureController.js).
  4. Automatisk omstart - Docker Compose-tjänsterna är konfigurerade med restart: unless-stopped för att säkerställa att de startar om automatiskt.

Förbättringsförslag

För ännu mer robusthet i framtiden kan vi:

  1. Konfigurera en systemd-service för att automatiskt starta Docker Compose vid systemomstart.
  2. Implementera automatiska säkerhetskopieringar av MongoDB-data.
  3. Sätta upp monitoring för systemresurser och applikationstillgänglighet.
  4. Konfigurera loggrotation för Docker-loggarna.

Branching-strategi

Medan vi implementerade driftsättningskonfigurationen i en separat branch (feature/docker-deployment), driftsattes den framgångsrikt utan att först mergas till main. I ett produktionsprojekt skulle vi idealt:

  1. Utveckla i feature branches
  2. Merga till en staging/testing-branch
  3. Testa i en staging-miljö
  4. Merga till main
  5. Driftsätta från main

Men för detta projekt fungerade vår strategi väl, med fullt fungerande driftsättning direkt från feature-branchen.