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:
- Öppnade https://mindtracker.se i en webbläsare
- Kontrollerade att HTTPS-omdirigering fungerade
- Testade att loginflödet fungerade
Nyckelinsikter från driftsättningen
- HTTPS-konfiguration var avgörande - Det var viktigt att konfigurera NGINX för både port 80 och 443, med korrekt omdirigering.
- Let's Encrypt-integration - För att integrera Let's Encrypt-certifikat med Docker behövde vi montera certifikatmappen i NGINX-containern.
- Filnamnskänslighet i Linux - Linux är skiftlägeskänsligt, vilket orsakade ett initialt problem med controllers-filen (ExposureController.js vs exposureController.js).
- 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:
- Konfigurera en systemd-service för att automatiskt starta Docker Compose vid systemomstart.
- Implementera automatiska säkerhetskopieringar av MongoDB-data.
- Sätta upp monitoring för systemresurser och applikationstillgänglighet.
- 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:
- Utveckla i feature branches
- Merga till en staging/testing-branch
- Testa i en staging-miljö
- Merga till main
- 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.