Building Docker Images from Docker File
Apa itu docker file?
Dockerfile adalah sebuah skrip berisi instruksi untuk membangun sebuah Docker Image. Dalam kata lain, Dockerfile adalah resep yang mendefinisikan apa saja yang akan ada di dalam image dan kontainer Docker. Dockerfile digunakan oleh perintah docker build untuk membuat Docker image baru.
Basic Sintax
Beberapa instruksi dasar dalam Dockerfile meliputi:
FROM: Mendefinisikan gambar dasar yang akan digunakan.RUN: Menjalankan perintah di dalam gambar.COPY: Menyalin file atau direktori dari host ke dalam gambar.EXPOSE: Membuka port pada kontainer.CMD: Menentukan perintah default yang akan dijalankan saat kontainer dimulai.
Building Image from a docker file
study case : buid simple api apps using fast api
1.buat file main.py
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def read_root():
return {"message": "Hello, World!"}
2.buat file Dockerfile
# layer 1 : Gunakan based image
FROM python:3.10
# layer 2 : Atur direktori kerja
WORKDIR /app
# layer 3 : Pasang dependensi
RUN pip install fastapi uvicorn
# layer 4: Salin file main.py ke direktori kerja /app
COPY ./main.py /app/
# layer 5 : Jalankan aplikasi
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]Apa Itu Docker Layers?
Docker Layers adalah unit terkecil dalam Docker Image, yang dibangun secara bertahap berdasarkan instruksi dalam Dockerfile. Setiap perintah dalam Dockerfile seperti FROM, RUN, COPY, atau ADD menciptakan lapisan baru (layer).
Bagaimana Layers Bekerja?
- Layered Filesystem:
- Docker Image terdiri dari beberapa layer yang bersifat read-only.
- Kontainer Docker menambahkan layer tambahan yang bersifat writable untuk menjalankan aplikasi.
- Caching:
- Docker menyimpan setiap layer secara terpisah. Jika layer tidak berubah, Docker menggunakan cache untuk mempercepat proses build.
- Layer yang sama dapat digunakan oleh beberapa image, sehingga menghemat ruang penyimpanan.
- Reusability:
- Layer yang tidak berubah dapat digunakan ulang oleh Docker di berbagai image dan kontainer.
3.run code berikut, pastikan anda sudah berada di dalam path yg terdapat file Dockerfile
docker build -t <image_name>:<tag> .
docker build -t my-fastapi-app:latest .
#ket:
-t : tag_name-error jika file Dockerfile tidak ditemukan

jika Dockerfile ditemukan, maka file tersebut akan dieksekusi tiap layernya

4.setelah berhasil membuat docker image, kita cek dengan perintah docker images

5.kemudian kita coba jalankan container dari docker image yang telah kita buat
docker run --name <container_name> -d -p <port_local>:<port_docker_img> <docker_img_name>
docker run --name fast-api -d -p 8000:8000 my-fastapi-app6.untuk memastikan container sudah berjalan cek list container dan log dari container
docker container ls
docker logs <container_name>
docker logs fast-api
aplikasi sudah berjalan di localhost:8000
7.cek di broswer


Optimizing Dockerfiles
Beberapa tips untuk mengoptimalkan Dockerfile:
- Penggabungan Instruksi: Anda bisa menggabungkan beberapa perintah
RUNmenjadi satu untuk mengurangi jumlah lapisan, tetapi perhatikan trade-off ini bisa mempengaruhi kecepatan caching.
- Hapus Sumber Daya yang Tidak Dibutuhkan: Pastikan untuk menghapus cache atau sumber daya temporer yang tidak dibutuhkan di dalam gambar.
Best Practice Make Docker File
1. Pilih Base Image dengan Bijak
- Gunakan official images atau images yang sudah terpercaya untuk keamanan.
- Pilih base image yang minimalis (misalnya,
alpine) jika memungkinkan, untuk mengurangi ukuran image.node:alpine
- Hindari menggunakan base image
latest, karena bisa menyebabkan ketidakpastian versi. Gunakan versi spesifik:python:3.9-slim
2. Gunakan Multi-Stage Builds
- Untuk aplikasi yang memerlukan build (seperti Node.js atau Go), gunakan multi-stage builds untuk memisahkan build dependencies dari runtime dependencies, sehingga image lebih kecil.
FROM node:16 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
FROM node:16-alpine
WORKDIR /app
COPY --from=builder /app .
CMD ["npm", "start"]
3. Urutkan Instruksi dengan Efisien
- Instruksi seperti
RUN,COPY, danADDmenghasilkan layer baru. Urutkan instruksi berdasarkan perubahan yang paling jarang terjadi untuk mengoptimalkan cache.
# Install dependencies first (jarang berubah)
COPY package.json .
RUN npm install
# Tambahkan kode (sering berubah)
COPY . .
4. Hindari Penggunaan Root User
- Jalankan aplikasi dengan user non-root untuk meningkatkan keamanan.
RUN useradd -m appuser
USER appuser5. Minimalkan Ukuran Image
- Gunakan Alpine atau versi slim dari base image jika memungkinkan.
- Bersihkan dependencies yang tidak diperlukan setelah instalasi.
RUN apt-get update && apt-get install -y \
curl \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
6. Gunakan .dockerignore
- Tambahkan file
.dockerignoreuntuk mengecualikan file yang tidak perlu ke dalam image (misalnya,node_modules, file konfigurasi lokal). Contoh.dockerignore:
node_modules
.git
*.log
7. Selalu Gunakan CMD atau ENTRYPOINT
- Gunakan
CMDuntuk mendefinisikan default command container.CMD ["npm", "start"]
- Gunakan
ENTRYPOINTjika container selalu menjalankan proses tertentu.ENTRYPOINT ["python", "app.py"]
8. Hindari RUN yang Redundant
- Gabungkan beberapa perintah
RUNuntuk mengurangi layer
RUN apt-get update && apt-get install -y \
curl \
vim
9. Gunakan ENV untuk Konfigurasi
- Simpan konfigurasi penting dalam variabel lingkungan (
ENV) agar mudah diubah.
ENV PORT=8080
ENV NODE_ENV=production
10. Dokumentasikan Dockerfile
- Tambahkan komentar untuk menjelaskan maksud dari setiap langkah.
# Menggunakan base image Node.js versi 16
FROM node:16
11. Amankan Image
- Jangan menyimpan kredensial sensitif dalam Dockerfile. Gunakan secrets atau environment variables.
- Jika memungkinkan, gunakan scanner keamanan untuk memeriksa kerentanan:
docker scan <image name>
12. Testing dan Debugging
- Uji image dengan menjalankannya dalam container dan pastikan semua service berfungsi dengan baik.
- Debug Dockerfile dengan menjalankan container dalam mode interactive:
docker run -it <image_name> sh
Contoh Dockerfile Sederhana
Berikut adalah contoh Dockerfile untuk aplikasi Node.js:
# Base image
FROM node:16-alpine
# Set working directory
WORKDIR /app
# Copy dependencies file
COPY package.json .
# Install dependencies
RUN npm install
# Copy application code
COPY . .
# Set environment variables
ENV PORT=3000
# Expose port
EXPOSE 3000
# Run application
CMD ["npm", "start"]