Masalah yang ingin diselesaikan
Tutorial origami biasanya tersebar di video dan blog. Urutannya tidak jelas dan tidak dikelompokkan berdasarkan level, sehingga pemula sering bingung harus mulai dari model yang mana. OrigamiPedia mengumpulkan tutorial dalam satu katalog dengan filter tingkat kesulitan (mudah, sedang, sulit) dan langkah-langkah yang berurutan.
Selain memecahkan masalah pengorganisasian konten, proyek statis ini sengaja dipilih sebagai sarana ideal untuk melatih perancangan arsitektur aplikasi 3-tier yang diorkestrasi menggunakan Docker Compose. Penguasaan infrastruktur backend yang stabil ini menjadi pondasi krusial yang selaras dengan tujuan karier saya di irisan Cloud Engineering dan Artificial Intelligence, khususnya untuk kebutuhan deployment model ke tahap produksi.
Proyek ini sengaja dibuat sederhana supaya fokusnya ada pada containerization dan arsitektur tiga tier, bukan pada banyaknya fitur.
Arsitektur
Aplikasi berjalan di tiga container dalam satu network buatan bernama origami-net. Container app menjalankan Flask dengan Gunicorn dan melayani halaman web sekaligus API di port 8000. Container db menjalankan PostgreSQL 16. Datanya disimpan di named volume pgdata, dan port 5432 sengaja tidak dibuka ke localhost sehingga hanya container lain di network yang sama yang bisa mengaksesnya. Container ketiga, Adminer, hanya menyala bila dipanggil dengan profile tools dan dipakai untuk melihat isi database.
Alur request-nya: browser mengakses localhost:8000, diteruskan ke app, lalu app memanggil database lewat nama service db, dan data tersimpan di volume.
Dockerfile
Dockerfile memakai multi-stage build. Stage pertama (builder) hanya menginstal dependency, sedangkan stage kedua mengambil hasil instalasi itu sehingga alat build tidak ikut ke image akhir.
FROM python:3.12.7-slim AS builder
WORKDIR /build
COPY requirements.txt .
RUN pip install --no-cache-dir --prefix=/install -r requirements.txt
FROM python:3.12.7-slim
WORKDIR /app
COPY --from=builder /install /usr/local
COPY app.py .
COPY templates ./templates
COPY static ./static
EXPOSE 8000
CMD ["gunicorn", "--bind", "0.0.0.0:8000", "app:app"]
Base image memakai tag versi spesifik, bukan latest, supaya hasil build selalu sama. File requirements.txt disalin sebelum source code agar layer instalasi bisa memakai cache; kalau hanya app.py yang berubah, library tidak diinstal ulang. Saya memakai COPY, bukan ADD, karena ADD punya perilaku tambahan seperti mengunduh dari URL dan mengekstrak file tar. CMD memakai exec form supaya Gunicorn menjadi proses utama dan menerima sinyal stop dengan benar. Untuk aplikasi sekecil ini selisih ukuran image dari multi-stage tidak besar, tetapi polanya penting untuk aplikasi yang lebih besar.
Docker Compose
Berikut bagian pentingnya (disingkat):
services:
app:
build: .
ports:
- "${APP_PORT:-8000}:8000"
environment:
DB_HOST: db
depends_on:
db:
condition: service_healthy
networks:
- origami-net
db:
image: postgres:16-alpine
volumes:
- pgdata:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${DB_USER} -d ${DB_NAME}"]
interval: 5s
timeout: 5s
retries: 5
networks:
- origami-net
Service db punya healthcheck memakai pg_isready, dan app memakai depends_on dengan condition: service_healthy, jadi aplikasi baru dijalankan setelah database benar-benar siap. Aplikasi terhubung ke database lewat nama service db, bukan IP atau localhost. Data database disimpan di named volume pgdata. Password dan konfigurasi dibaca dari file .env yang tidak di-commit; yang ada di repository hanya .env.example berisi data dummy.
Menjalankan di localhost
git clone https://github.com/marvin173-digital/Origami-Pedia.git
cd Origami-Pedia
cp .env.example .env
docker compose up -d --build
Lalu buka http://localhost:8000. Untuk melihat database, jalankan docker compose --profile tools up -d dan buka http://localhost:8081.
Hasil
Saya menguji persistensi dengan menambah data, menjalankan docker compose down, lalu docker compose up -d. Datanya masih ada karena disimpan di volume pgdata. Kalau memakai docker compose down -v, volume ikut terhapus dan database kembali kosong.
Pelajaran yang didapat
- Port 8080 di laptop saya sudah terpakai, jadi port Adminer saya pindahkan ke 8081.
- Error YAML terjadi karena satu kunci
imagetertulis di service yang salah; indentasi dan struktur YAML harus benar-benar teliti. - Gambar tidak tampil sampai folder
staticikut di-COPYdan image dibuild ulang. Perubahan file harus diikutidocker compose up -d --build. - Service yang memakai profile tidak ikut dimatikan oleh
docker compose downbiasa, jadi perlu--profile tools. - Waktu login Adminer, pilihan System-nya masih MySQL dan kolom Database kosong, jadi muncul error “Connection refused” dan “relation does not exist”. Ternyata harus memilih PostgreSQL, server db, dan mengisi nama database.
- Di PowerShell, curl adalah alias perintah lain, jadi harus memakai curl.exe. Mengirim JSON juga lebih aman lewat file (data.json) daripada ditulis langsung karena masalah tanda kutip.
Tautan
- Repository GitHub: https://github.com/marvin173-digital/Origami-Pedia
- Video demo: https://youtu.be/3tUQnIgfwqQ



Top comments (0)