Artikel ini tersedia dalam Bahasa Inggris

🇬🇧 Read in English

30 Mei 2026

🇮🇩 Bahasa Indonesia

Fleet Management Part 8: DevSecOps, CI/CD & Deployment Production

Pipeline DevSecOps lengkap dengan GitHub Actions. Security scanning, Docker, CI/CD, monitoring, dan deployment production untuk aplikasi enterprise.

4 min read

Apa itu DevSecOps?

Pengembangan tradisional:

Developer bangun → QA test → Audit security → Operations deploy (minggu) (hari) (hari) (jam)

DevSecOps mengintegrasikan security dan operations ke setiap langkah:

Kode → Lint → Test → Security Scan → Build → Deploy → Monitor ↑ ↑ ↑ ↑ ↑ ↑ Otomatis Otomatis Otomatis Otomatis Otomatis Otomatis

Ide kuncinya: Security bukan fase — melainkan praktik. Setiap commit di-lint, di-test, di-scan, dan di-deploy otomatis.


Git Workflow: Strategi Branching

main ─────────────────────────────────→ Production │ ↑ ├── feature/fleet-dashboard ───┤ (Pull Request + Review) ├── feature/nestjs-api ────────┤ └── fix/gps-timeout ───────────┘

Konvensi Commit

feat(fleet): tambah komponen peta tracking kendaraan fix(telemetry): perbaiki timeout data GPS di koneksi lambat docs(api): tambah dokumentasi swagger untuk endpoint fleet refactor(auth): ekstrak validasi JWT ke guard test(driver): tambah unit test untuk cek expired lisensi

Mengapa ini penting: Release notes otomatis, histori git yang jelas, dan mudah dicari.


Pipeline CI/CD dengan GitHub Actions

name: CI/CD Pipeline

on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main]

jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with: { node-version: '20', cache: 'npm' }
      - run: npm ci
      - run: npm run lint
      - run: npm run type-check

  test:
    runs-on: ubuntu-latest
    needs: lint
    services:
      postgres:
        image: postgres:16
        env: { POSTGRES_DB: fleet_test, POSTGRES_USER: test, POSTGRES_PASSWORD: test }
        ports: ['5432:5432']
      redis:
        image: redis:7
        ports: ['6379:6379']
    steps:
      - uses: actions/checkout@v4
      - run: npm ci
      - run: npm run test:unit
      - run: npm run test:e2e

  security:
    runs-on: ubuntu-latest
    needs: lint
    steps:
      - uses: actions/checkout@v4
      - run: npm audit --audit-level=high
      - name: Run Semgrep
        uses: returntocorp/semgrep-action@v1
        with:
          config: p/typescript

  deploy:
    runs-on: ubuntu-latest
    needs: [test, security]
    if: github.ref == 'refs/heads/main'
    steps:
      - uses: actions/checkout@v4
      - run: docker build -t fleet-api:${{ github.sha }} .
      - name: Deploy ke production
        run: |
          ssh deploy@${{ secrets.SERVER_IP }} << 'EOF'
            cd /var/www/fleet-api
            git pull origin main
            npm ci --production
            npm run build
            pm2 restart fleet-api
          EOF
StageApa yang DicekWaktuBlock Deploy?
LintGaya kode, error TypeScript~30 detik✅ Ya
TestUnit + E2E test lulus~2 menit✅ Ya
SecurityScanning vulnerability~1 menit✅ Ya
DeployBuild + deploy ke server~3 menitN/A

Security Scanning

SAST (Static Application Security Testing)

// Semgrep menangkap pola-pola ini:

// ❌ Vulnerability SQL Injection
const query = `SELECT * FROM users WHERE id = '${userId}'`;

// ✅ Aman — parameterized query
const query = 'SELECT * FROM users WHERE id = $1';
await pool.query(query, [userId]);

// ❌ Hardcoded secret
const API_KEY = 'sk_live_abc123secret';

// ✅ Aman — gunakan environment variable
const API_KEY = process.env.API_KEY;

Docker: Containerization

# Stage 1: Build
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

# Stage 2: Production (image lebih kecil)
FROM node:20-alpine AS production
WORKDIR /app
COPY package*.json ./
RUN npm ci --production && npm cache clean --force
COPY --from=builder /app/dist ./dist

# Security: Jangan jalankan sebagai root
RUN addgroup -g 1001 appgroup && adduser -S -u 1001 -G appgroup appuser
USER appuser

EXPOSE 3001
CMD ["node", "dist/main.js"]

Mengapa multi-stage? Stage build punya devDependencies (300MB+). Stage production hanya punya yang dibutuhkan untuk berjalan (~80MB). Image lebih kecil = deploy lebih cepat + attack surface lebih kecil.


Monitoring & Health Check

@Controller('health')
export class HealthController {
  @Get()
  async check() {
    return this.health.check([
      () => this.db.pingCheck('database'),
      () => this.redis.pingCheck('redis'),
    ]);
  }
}

Structured Logging

// Gunakan log JSON terstruktur — bukan console.log
this.logger.log({
  event: 'delivery_created',
  deliveryId: delivery.id,
  vehicleId: delivery.vehicleId,
  timestamp: new Date().toISOString(),
});

Playbook Incident Response

SeverityContohWaktu ResponseSiapa
P0 - KritisSistem down15 menitOn-call + Tech Lead
P1 - TinggiData GPS terlambat > 5 menit1 jamOn-call developer
P2 - SedangAdmin panel lambat4 jamDeveloper assigned
P3 - RendahBug UI, masalah kosmetikSprint berikutnyaDeveloper manapun

Rekap Seri

Selamat! Dalam 8 bagian, kita telah membangun Fleet Management System enterprise yang lengkap:

PartTopikSkill yang Didemonstrasikan
1Arsitektur SistemSDLC, desain arsitektur, keputusan tech stack
2Dashboard Next.jsTypeScript, React, SSR, arsitektur komponen
3Backend NestJSNestJS, DI, DTO, clean architecture
4Admin LaravelPHP, Laravel, Filament, arsitektur event-driven
5Desain DatabasePostgreSQL, MySQL, Redis, polyglot persistence
6Prinsip SOLIDClean code, design pattern, code review
7MicroservicesService boundaries, saga pattern, API gateway
8DevSecOpsCI/CD, security scanning, Docker, deployment

Ini bukan hanya teori — ini adalah pattern dan praktik yang saya gunakan sehari-hari sebagai developer full-stack senior. Kemampuan untuk merancang, membangun, mengamankan, dan men-deploy aplikasi enterprise end-to-end adalah yang membedakan developer senior.


Seri Fleet Management System selesai. Jika ini bermanfaat, lihat juga seri Laravel E-Learning dan React Native Event Management. Silakan hubungi saya jika ada pertanyaan!

Lanjut Membaca

Previous article thumbnail

← Artikel Sebelumnya

Fleet Management Part 7: From Monolith to Microservices

Artikel Selanjutnya →

Rebuilding My Laravel E-Learning App: A Journey from 5.2 to Modern Laravel

Next article thumbnail