Pelajari cara mengekspos dan memublikasikan port di Docker secara efektif untuk mengaktifkan komunikasi antara container Anda dan dunia luar. Panduan ini mencakup semuanya, mulai dari konfigurasi Dockerfile dan flag runtime hingga orkestrasi Docker Compose dan teknik pemecahan masalah.
Saat bekerja dengan container Docker, salah satu aspek paling krusial yang saya temui adalah mengaktifkan komunikasi jaringan antara container dan dunia luar. Tanpa konfigurasi port yang tepat, aplikasi yang dikontainerisasi akan tetap terisolasi dan tidak dapat diakses. Dalam artikel ini, saya akan memandu Anda melalui proses mengekspos port Docker, sebuah keterampilan fundamental bagi siapa pun yang bekerja dengan aplikasi terkontainerisasi.
Panduan ini dirancang khusus untuk pengembang perangkat lunak, engineer DevOps, dan profesional TI yang perlu membuat aplikasi terkontainerisasi mereka dapat diakses oleh pengguna, layanan lain, atau sistem eksternal. Baik Anda menerapkan server web, API, atau database di dalam container, memahami eksposur port sangat penting untuk membangun sistem berbasis Docker yang fungsional.
Di akhir artikel ini, Anda akan memiliki pemahaman yang jelas tentang cara kerja jaringan Docker, berbagai metode untuk mengekspos port, dan teknik praktis untuk menerapkan konsep-konsep ini dalam proyek Anda sendiri.
Sebelum masuk ke detail teknis, penting untuk memahami apa arti eksposur port dalam ekosistem Docker.
Prinsip isolasi jaringan container
Container Docker dirancang dengan isolasi sebagai prinsip inti. Isolasi ini dicapai melalui fitur kernel Linux seperti namespace dan cgroups. Namespace menyediakan isolasi proses, memastikan bahwa proses dalam sebuah container tidak dapat melihat atau berinteraksi dengan proses di container lain atau sistem host. Di sisi lain, cgroups mengendalikan alokasi sumber daya, membatasi seberapa banyak CPU, memori, dan sumber daya lainnya yang dapat dikonsumsi oleh container.
Dari perspektif jaringan, setiap container menerima namespace jaringannya sendiri, lengkap dengan antarmuka Ethernet virtual (pasangan veth). Antarmuka ini secara default terhubung ke jaringan bridge Docker, memungkinkan komunikasi antar-container sambil mempertahankan isolasi dari jaringan host. Anggaplah ini seperti setiap container memiliki alamat jaringan privatnya sendiri, yang tidak terlihat oleh dunia luar.
Dalam konfigurasi defaultnya, sebuah container Docker sepenuhnya terisolasi. Layanan yang berjalan di dalamnya dapat saling berkomunikasi, tetapi tidak dapat dijangkau dari luar container, bahkan dari mesin host. Di sinilah eksposur port menjadi diperlukan.
Expose vs publish: perbedaan semantik
Saat bekerja dengan konfigurasi port Docker, Anda akan menemukan dua konsep yang terkait namun berbeda: expose dan publish.
Expose port pada dasarnya adalah fitur dokumentasi. Ketika Anda mengekspos port di Docker, Anda menambahkan metadata ke image container Anda, yang menunjukkan bahwa aplikasi dalam container mendengarkan pada port-port tertentu.
Namun, mengekspos port tidak benar-benar membuatnya dapat diakses dari luar container. Ini berfungsi sebagai dokumentasi bagi pengguna image Anda.
Publish port adalah yang benar-benar membuat layanan dalam container Anda tersedia bagi dunia luar. Publish membuat pemetaan antara port pada mesin host dan port di dalam container. Saat Anda memublikasikan port, Docker mengonfigurasi jaringan host untuk meneruskan trafik dari port host yang ditentukan ke port container yang sesuai.
Berikut kapan menggunakan masing-masing pendekatan:
Gunakan expose saat Anda membuat image yang ditujukan untuk digunakan oleh pengguna Docker lain, untuk mendokumentasikan port mana yang digunakan aplikasi Anda.
Gunakan publish saat Anda membutuhkan sistem eksternal (termasuk host) untuk mengakses layanan yang berjalan di dalam container Anda.
Gunakan keduanya sekaligus untuk dokumentasi dan fungsionalitas yang lengkap, terutama di lingkungan produksi.
Cara Mengekspos Port Docker
Sekarang kita memahami konsepnya, mari lihat aspek praktis mengekspos port Docker dalam berbagai konteks.
Strategi deklarasi Dockerfile
Cara paling dasar untuk mengekspos port adalah dengan menggunakan instruksi EXPOSE dalam Dockerfile Anda. Ini menyatakan port yang dirancang untuk digunakan oleh container.
FROM my-image:latestEXPOSE 80EXPOSE 443Didukung oleh
Pada contoh ini, saya telah menentukan bahwa container akan menggunakan port 80 dan 443, yang merupakan standar untuk trafik HTTP (Hypertext Transfer Protocol) dan HTTPS (Hypertext Transfer Protocol Secure). Anda juga dapat menggabungkannya menjadi satu instruksi:
Saat menentukan port, praktik yang baik adalah menyertakan protokolnya, TCP (Transmission Control Protocol) atau UDP (User Datagram Protocol) jika aplikasi Anda menggunakan protokol tertentu:
Jika tidak ada protokol yang ditentukan, secara default dianggap TCP. Ini sesuai untuk sebagian besar aplikasi web, tetapi layanan seperti DNS (Domain Name System) atau server gim sering memerlukan UDP.
Dari perspektif keamanan, saya menyarankan hanya mengekspos port yang benar-benar dibutuhkan aplikasi Anda. Setiap port yang diekspos merepresentasikan potensi vektor serangan, sehingga meminimalkan jumlah port yang diekspos mengikuti prinsip least privilege.
Manajemen port saat runtime
Walaupun instruksi EXPOSE mendokumentasikan port yang digunakan container, agar port tersebut dapat diakses dari host atau mesin lain, Anda perlu memublikasikannya saat menjalankan container.
Berikut cara melakukan binding secara eksplisit antara port container dan port host tertentu:
Flag -p (atau --publish) memungkinkan Anda melakukan binding satu port atau rentang port di container ke host.
Perintah ini memetakan port 80 di dalam container ke port 8081 di host. Setelah menjalankan perintah ini, Anda dapat mengakses server web dengan membuka http://localhost:8081 di browser Anda.
Untuk kemudahan selama pengembangan, Docker menyediakan flag -P (P kapital) atau --publish-all, yang secara otomatis memublikasikan semua port yang diekspos ke port acak bernomor tinggi di host:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a7c53d9413bf image "/docker-.…"10 s ago Up 9 s 0.0.0.0:49153->80/tcp, :::49153->80/tcp wizardlDidukung oleh
Di sini, port 80 di dalam container dipetakan ke port 49153 di host.
Saat bekerja dengan layanan yang menggunakan TCP dan UDP pada port yang sama (seperti server DNS), Anda perlu menentukan protokol saat memublikasikan:
docker run -p53:53/tcp -p53:53/udp dns-serverDidukung oleh
Orkestrasi Docker Compose
Untuk aplikasi multi-container, Docker Compose menyediakan cara yang lebih mudah untuk mengonfigurasi jaringan dan port.
Dalam berkas YAML Docker Compose, Anda dapat menentukan pemetaan port di bawah kunci ports untuk setiap layanan:
services:web:image: my-image
ports:-"8081:80"-"443:443"api:build: ./api
ports:-"3000:3000"Didukung oleh
Docker Compose membuat pembedaan penting antara ports dan expose. Bagian ports membuat pemetaan port yang dipublikasikan dan dapat diakses dari luar, sedangkan expose hanya membuat port tersedia bagi layanan yang tertaut dalam jaringan Compose yang sama:
services:web:image: my-image
ports:-"8081:80"database:image: postgres
expose:-"5432"Didukung oleh
Pada contoh ini, layanan web dapat diakses dari host pada port 8081, tetapi database PostgreSQL hanya dapat diakses oleh layanan lain dalam berkas Compose, tidak langsung dari host.
Untuk konfigurasi yang fleksibel, terutama lintas lingkungan yang berbeda, saya dapat menggunakan variabel lingkungan dalam pemetaan port:
services:web:image: my-image
ports:-"${WEB_PORT:-8081}:80"Didukung oleh
Sintaks ini memungkinkan saya menentukan port host melalui variabel lingkungan (WEB_PORT), dengan default 8081 jika tidak diatur.
Mengekspos Port Docker - Contoh Penerapan
Mari kita lalui contoh lengkap mengekspos port Docker untuk aplikasi web dengan backend database.
Bayangkan kita membangun aplikasi web sederhana yang terdiri dari layanan API Python Flask dan database PostgreSQL. Layanan API mendengarkan pada port 5000, dan PostgreSQL menggunakan port defaultnya 5432.
Berikut tampilan aplikasi Flask sederhana kita (app.py). Aplikasi ini akan membuat database myapp dan akan mengambil data dari tabel items, setelah tabel ini dibuat di dalam database.
from flask import Flask, jsonify
import os
import psycopg2
app = Flask(__name__)# Database connection parameters from environment variables
DB_HOST = os.environ.get('DB_HOST','db')
DB_NAME = os.environ.get('DB_NAME','myapp')
DB_USER = os.environ.get('DB_USER','postgres')
DB_PASS = os.environ.get('DB_PASSWORD','postgres')@app.route('/')defindex():return jsonify({'message':'API is running'})@app.route('/items')defget_items():# Connect to the PostgreSQL database
conn = psycopg2.connect(
host=DB_HOST,
database=DB_NAME,
user=DB_USER,
password=DB_PASS
)# Create a cursor and execute a query
cur = conn.cursor()
cur.execute('SELECT id, name FROM items')# Fetch results and format as list of dictionaries
items =[{'id': row[0],'name': row[1]}for row in cur.fetchall()]# Close connections
cur.close()
conn.close()return jsonify(items)if __name__ =='__main__':# Run the Flask app, binding to all interfaces (important for Docker)
app.run(host='0.0.0.0', port=5000)Didukung oleh
Selanjutnya, saya akan membuat berkas requirements.txt kita:
Sekarang, saya perlu membuat Dockerfile untuk layanan API Python kita:
FROM python:3.9-slimWORKDIR /app# Install dependenciesCOPY requirements.txt .RUN pip install --no-cache-dir -r requirements.txt# Copy application codeCOPY . .# Expose the port Flask runs onEXPOSE 5000# Command to run the applicationCMD ["python", "app.py"]Didukung oleh
Terakhir, saya akan membuat berkas Docker Compose untuk mengorkestrasi kedua layanan:
Sekarang, saya dapat mengakses API di http://localhost:5000, tetapi instance PostgreSQL tidak dapat diakses langsung dari luar jaringan Docker, yang merupakan praktik keamanan yang baik untuk layanan database. Namun Anda dapat mengakses PostgreSQL dari container yang berjalan:
docker compose exec db psql -U postgres -d myappDidukung oleh
Perintah ini akan mengakses CLI PostgreSQL, tempat saya dapat melihat database dan membuat tabel items. Setelah dibuat, saya dapat melihat datanya di http://localhost:5000/items
Cara mengekspos banyak port Docker
Jika aplikasi Python saya perlu mengekspos beberapa port, saya dapat menentukannya semua di Dockerfile:
FROM python:3.9-slimWORKDIR /appCOPY requirements.txt .RUN pip install --no-cache-dir -r requirements.txtCOPY . .EXPOSE 5000 8081 9090CMD ["python", "app.py"]Didukung oleh
Dockerfile ini mengekspos:
Port 5000 untuk aplikasi Flask utama (saat ini aktif)
Port 8081 untuk dasbor pemantauan potensial
Port 9090 untuk antarmuka debugging di masa mendatang
Penting untuk dicatat bahwa meskipun saya telah mengekspos port 8081 dan 9090 di Dockerfile sebagai dokumentasi, aplikasi Flask saya saat ini hanya dikonfigurasi untuk mendengarkan pada port 5000. Port tambahan yang diekspos menunjukkan di mana fungsionalitas di masa depan mungkin akan diimplementasikan.
Cara memublikasikan port yang diekspos
Untuk memublikasikan port yang diekspos dalam Dockerfile, saya menggunakan flag -p atau -P saat menjalankan container:
Ini memetakan port 5000 di container (yang diekspos dalam Dockerfile dan tempat Flask mendengarkan) ke port 8081 di host. Setelah menjalankan perintah ini, saya dapat mengakses aplikasi Flask saya dengan membuka http://localhost:8081 di browser.
Saya juga dapat menggunakan flag -P untuk secara otomatis memublikasikan semua port yang diekspos ke port acak di host:
5000/tcp ->0.0.0.0:32768
8081/tcp ->0.0.0.0:32769
9090/tcp ->0.0.0.0:32770Didukung oleh
Perintah ini menampilkan semua pemetaan port untuk container tertentu. Misalnya, jika aplikasi Flask saya hanya mendengarkan pada port 5000 tetapi saya telah mengekspos beberapa port di Dockerfile, docker port akan menunjukkan dengan tepat port host mana yang dipetakan ke port container mana. Jadi, jika port 5000 telah dipetakan ke 32768, saya dapat mengakses aplikasi Flask saya melalui http://localhost:32768
Teknik Diagnostik dan Pemecahan Masalah
Bahkan dengan konfigurasi yang cermat, masalah dapat terjadi pada pemetaan port Docker. Berikut beberapa teknik yang saya gunakan untuk mendiagnosis dan menyelesaikan masalah umum.
Inspeksi pemetaan port
Langkah pertama dalam mendiagnosis masalah terkait port adalah memverifikasi bahwa pemetaan telah disetel dengan benar. Saya menggunakan perintah berikut:
Daftar semua container yang berjalan beserta pemetaan portnya:
Perintah docker inspect memberikan informasi terperinci, termasuk pengaturan jaringan. Untuk berfokus pada detail terkait jaringan, gunakan:
docker inspect --format='{{json .NetworkSettings.Ports}}'[container_id]| jqDidukung oleh
Jika Anda perlu melakukan analisis trafik yang lebih dalam, alat seperti tcpdump dan netstat dapat sangat berguna. Pertama, pastikan alat tersebut terpasang di dalam container. Jika container belum menyertakan alat ini, Anda dapat memasangnya dengan menjalankan perintah berikut:
Untuk melihat port mana yang didengarkan aplikasi di dalam container:
dockerexec-it[container_id]netstat-tulnDidukung oleh
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 000.0.0.0:5000 0.0.0.0:* LISTEN
tcp 00127.0.0.11:42265 0.0.0.0:* LISTEN
udp 00127.0.0.11:34267 0.0.0.0:*Didukung oleh
Ini menunjukkan, misalnya, bahwa aplikasi Flask mendengarkan pada semua antarmuka di port 5000.
Untuk memantau trafik masuk dan keluar pada antarmuka jaringan utama container (biasanya eth0):
dockerexec-it[container_id] tcpdump -i eth0Didukung oleh
listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytesDidukung oleh
Perintah ini memungkinkan Anda menelusuri trafik dan mengidentifikasi apakah permintaan mencapai container atau jika paket dijatuhkan atau salah diarahkan.
Analisis aturan iptables
Docker memanfaatkan iptables untuk mengelola Network Address Translation (NAT) dan mengendalikan aliran trafik antara host dan container. Docker secara otomatis memasukkan aturan untuk meneruskan port host ke IP dan port container yang sesuai, sehingga akses ke layanan dalam container menjadi mulus.
Pada host Linux native, Anda dapat memeriksa aturan ini menggunakan perintah seperti:
Ini menunjukkan bagaimana Docker memetakan trafik masuk pada port host tertentu ke endpoint container. Berdasarkan berkas Docker Compose sebelumnya, Anda akan melihat port yang diteruskan:
DNAT mengarahkan ulang trafik dari host ke container.
RETURN memastikan routing yang tepat untuk trafik jaringan internal Docker.
Namun, bergantung pada lingkungan Anda (misalnya, Docker Desktop di Windows atau WSL2), Docker mungkin menangani penerusan port secara berbeda, dan aturan iptables mungkin tidak terlihat atau tidak dapat diubah dari dalam sistem. Dalam kasus ini, Anda dapat memeriksa penerusan port dengan perintah berikut:
Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port
tcp LISTEN 04096 *:5000 *:*
tcp LISTEN 04096 *:8081 *:*
tcp LISTEN 04096 *:9090 *:* Didukung oleh
Tips pemecahan masalah:
Konfirmasikan pemetaan port dengan docker ps dan docker port [container].
Periksa apakah firewall sistem host atau perangkat lunak keamanan memblokir port.
Gunakan log container dan alat jaringan seperti netstat dan tcpdump untuk memverifikasi perilaku jaringan aplikasi Anda.
Kesimpulan
Mengekspos port Docker adalah keterampilan fundamental yang menjembatani kesenjangan antara isolasi container dan kegunaan praktis. Sepanjang artikel ini, saya telah menjelaskan cara kerja model jaringan Docker, perbedaan antara mengekspos dan memublikasikan port, serta memberikan contoh praktis untuk berbagai skenario.
Ingat poin-poin kunci ini:
Gunakan EXPOSE dalam Dockerfile untuk mendokumentasikan port yang digunakan aplikasi Anda
Gunakan -p atau -P saat menjalankan container untuk membuat port tersebut dapat diakses dari luar
Manfaatkan Docker Compose untuk mengelola aplikasi multi-container yang kompleks
Gunakan alat diagnostik untuk memecahkan masalah saat muncul
Menguasai konsep dan teknik ini akan memungkinkan Anda merancang aplikasi terkontainerisasi yang lebih tangguh, yang berkomunikasi secara efektif baik secara internal maupun dengan dunia luar. Baik Anda mengembangkan aplikasi web sederhana atau arsitektur microservices yang kompleks, pengelolaan port yang tepat sangat krusial untuk keberhasilan.
Seiring container terus mendominasi strategi penerapan aplikasi modern, kemampuan untuk dengan percaya diri mengelola jaringan dan port Docker akan tetap menjadi keterampilan esensial dalam perangkat kerja setiap pengembang.
Untuk terus belajar, pastikan untuk melihat sumber daya berikut:
Mengekspos port di Docker adalah cara untuk mendokumentasikan port mana yang didengarkan oleh aplikasi terkontainerisasi Anda, tetapi ini tidak membuat port tersebut dapat diakses di luar container.
Bagaimana cara membuat port container Docker dapat diakses dari mesin host saya?⌄
Anda memublikasikan port menggunakan flag -p dengan docker run atau bagian ports di Docker Compose, yang memetakan port host ke port container.
Apa perbedaan antara `EXPOSE` dan `-p` di Docker?⌄
EXPOSE digunakan dalam Dockerfile untuk mendeklarasikan port sebagai dokumentasi, sedangkan -p memublikasikan dan memetakan port tersebut untuk akses eksternal.
Bisakah saya mengekspos beberapa port untuk satu container Docker?⌄
Ya, Anda dapat mengekspos beberapa port menggunakan beberapa instruksi EXPOSE dalam Dockerfile atau dengan menentukan beberapa port di bagian ports Docker Compose.
Bagaimana cara memecahkan masalah pemetaan port Docker?⌄
Gunakan perintah seperti docker ps, docker port, docker inspect, dan alat jaringan di dalam container (misalnya, netstat, tcpdump) untuk memverifikasi pemetaan port dan aliran trafik.
Sebagai Founder Martin Data Solutions serta Data Scientist, ML, dan AI Engineer lepas, saya memiliki portofolio beragam dalam Regression, Classification, NLP, LLM, RAG, Neural Networks, Ensemble Methods, dan Computer Vision.
Berhasil mengembangkan sejumlah proyek ML end-to-end, termasuk pembersihan data, analitik, pemodelan, dan deployment di AWS dan GCP, menghadirkan solusi yang berdampak dan dapat diskalakan.
Membangun aplikasi web yang interaktif dan skalabel menggunakan Streamlit dan Gradio untuk berbagai use case industri.
Mengajar dan membimbing mahasiswa dalam data science dan analitik, mendorong perkembangan profesional mereka melalui pendekatan pembelajaran yang dipersonalisasi.
Merancang konten kursus untuk aplikasi retrieval-augmented generation (RAG) yang disesuaikan dengan kebutuhan enterprise.
Menulis blog teknis AI & ML berdampak tinggi, mencakup topik seperti MLOps, vector database, dan LLM, dengan capaian keterlibatan yang signifikan.
Dalam setiap proyek yang saya tangani, saya memastikan menerapkan praktik terkini dalam rekayasa perangkat lunak dan DevOps, seperti CI/CD, code linting, formatting, pemantauan model, pelacakan eksperimen, dan penanganan error yang tangguh. Saya berkomitmen menyajikan solusi menyeluruh, mengubah wawasan data menjadi strategi praktis yang membantu bisnis bertumbuh dan memaksimalkan pemanfaatan data science, machine learning, dan AI.
Kuasai pertanyaan wawancara basis data, dari konsep SQL dasar hingga skenario desain sistem tingkat lanjut. Panduan mendalam ini mencakup semua yang Anda perlukan untuk sukses di wawancara DBMS dan meraih peran berikutnya.
Temukan alasan mengapa Anda sebaiknya (tidak) menggunakan spaghetti plot untuk menyampaikan ketidakpastian jalur prediksi badai serta dampaknya terhadap interpretasi.
Pelajari kekuatan Docker dan Kubernetes, jalur interaktif ini akan memungkinkan Anda untuk membangun dan mengimplementasikan aplikasi di lingkungan modern.
Telusuri lebih dalam keahlian tingkat lanjut dan alat-alat terkini yang merevolusi peran insinyur data saat ini melalui program Professional Data Engineer kami.
Saat bekerja dengan container Docker, salah satu aspek paling krusial yang saya temui adalah mengaktifkan komunikasi jaringan antara container dan dunia luar. Tanpa konfigurasi port yang tepat, aplikasi yang dikontainerisasi akan tetap terisolasi dan tidak dapat diakses. Dalam artikel ini, saya akan memandu Anda melalui proses mengekspos port Docker, sebuah keterampilan fundamental bagi siapa pun yang bekerja dengan aplikasi terkontainerisasi.
Panduan ini dirancang khusus untuk pengembang perangkat lunak, engineer DevOps, dan profesional TI yang perlu membuat aplikasi terkontainerisasi mereka dapat diakses oleh pengguna, layanan lain, atau sistem eksternal. Baik Anda menerapkan server web, API, atau database di dalam container, memahami eksposur port sangat penting untuk membangun sistem berbasis Docker yang fungsional.
Di akhir artikel ini, Anda akan memiliki pemahaman yang jelas tentang cara kerja jaringan Docker, berbagai metode untuk mengekspos port, dan teknik praktis untuk menerapkan konsep-konsep ini dalam proyek Anda sendiri.
Jika Anda baru mengenal Docker, pertimbangkan untuk mengikuti salah satu kursus kami, seperti Introduction to Docker, Containerization and Virtualization with Docker and Kubernetes, Intermediate Docker, atau Containerization and Virtualization Concepts.
Apa itu Mengekspos Port di Docker?
Sebelum masuk ke detail teknis, penting untuk memahami apa arti eksposur port dalam ekosistem Docker.
Prinsip isolasi jaringan container
Container Docker dirancang dengan isolasi sebagai prinsip inti. Isolasi ini dicapai melalui fitur kernel Linux seperti namespace dan cgroups. Namespace menyediakan isolasi proses, memastikan bahwa proses dalam sebuah container tidak dapat melihat atau berinteraksi dengan proses di container lain atau sistem host. Di sisi lain, cgroups mengendalikan alokasi sumber daya, membatasi seberapa banyak CPU, memori, dan sumber daya lainnya yang dapat dikonsumsi oleh container.
Dari perspektif jaringan, setiap container menerima namespace jaringannya sendiri, lengkap dengan antarmuka Ethernet virtual (pasangan veth). Antarmuka ini secara default terhubung ke jaringan bridge Docker, memungkinkan komunikasi antar-container sambil mempertahankan isolasi dari jaringan host. Anggaplah ini seperti setiap container memiliki alamat jaringan privatnya sendiri, yang tidak terlihat oleh dunia luar.
Dalam konfigurasi defaultnya, sebuah container Docker sepenuhnya terisolasi. Layanan yang berjalan di dalamnya dapat saling berkomunikasi, tetapi tidak dapat dijangkau dari luar container, bahkan dari mesin host. Di sinilah eksposur port menjadi diperlukan.
Expose vs publish: perbedaan semantik
Saat bekerja dengan konfigurasi port Docker, Anda akan menemukan dua konsep yang terkait namun berbeda: expose dan publish.
Expose port pada dasarnya adalah fitur dokumentasi. Ketika Anda mengekspos port di Docker, Anda menambahkan metadata ke image container Anda, yang menunjukkan bahwa aplikasi dalam container mendengarkan pada port-port tertentu.
Namun, mengekspos port tidak benar-benar membuatnya dapat diakses dari luar container. Ini berfungsi sebagai dokumentasi bagi pengguna image Anda.
Publish port adalah yang benar-benar membuat layanan dalam container Anda tersedia bagi dunia luar. Publish membuat pemetaan antara port pada mesin host dan port di dalam container. Saat Anda memublikasikan port, Docker mengonfigurasi jaringan host untuk meneruskan trafik dari port host yang ditentukan ke port container yang sesuai.
Berikut kapan menggunakan masing-masing pendekatan:
Cara Mengekspos Port Docker
Sekarang kita memahami konsepnya, mari lihat aspek praktis mengekspos port Docker dalam berbagai konteks.
Strategi deklarasi Dockerfile
Cara paling dasar untuk mengekspos port adalah dengan menggunakan instruksi
EXPOSEdalam Dockerfile Anda. Ini menyatakan port yang dirancang untuk digunakan oleh container.Pada contoh ini, saya telah menentukan bahwa container akan menggunakan port
80dan443, yang merupakan standar untuk trafik HTTP (Hypertext Transfer Protocol) dan HTTPS (Hypertext Transfer Protocol Secure). Anda juga dapat menggabungkannya menjadi satu instruksi:Saat menentukan port, praktik yang baik adalah menyertakan protokolnya, TCP (Transmission Control Protocol) atau UDP (User Datagram Protocol) jika aplikasi Anda menggunakan protokol tertentu:
Jika tidak ada protokol yang ditentukan, secara default dianggap TCP. Ini sesuai untuk sebagian besar aplikasi web, tetapi layanan seperti DNS (Domain Name System) atau server gim sering memerlukan UDP.
Dari perspektif keamanan, saya menyarankan hanya mengekspos port yang benar-benar dibutuhkan aplikasi Anda. Setiap port yang diekspos merepresentasikan potensi vektor serangan, sehingga meminimalkan jumlah port yang diekspos mengikuti prinsip least privilege.
Manajemen port saat runtime
Walaupun instruksi
EXPOSEmendokumentasikan port yang digunakan container, agar port tersebut dapat diakses dari host atau mesin lain, Anda perlu memublikasikannya saat menjalankan container.Berikut cara melakukan binding secara eksplisit antara port container dan port host tertentu:
Flag
-p(atau--publish) memungkinkan Anda melakukan binding satu port atau rentang port di container ke host.Perintah ini memetakan port 80 di dalam container ke port 8081 di host. Setelah menjalankan perintah ini, Anda dapat mengakses server web dengan membuka
http://localhost:8081di browser Anda.Untuk kemudahan selama pengembangan, Docker menyediakan flag
-P(P kapital) atau--publish-all, yang secara otomatis memublikasikan semua port yang diekspos ke port acak bernomor tinggi di host:Untuk mengetahui port host mana yang ditetapkan, saya dapat menggunakan perintah
docker ps:Ini akan menampilkan keluaran seperti:
Di sini, port 80 di dalam container dipetakan ke port 49153 di host.
Saat bekerja dengan layanan yang menggunakan TCP dan UDP pada port yang sama (seperti server DNS), Anda perlu menentukan protokol saat memublikasikan:
Orkestrasi Docker Compose
Untuk aplikasi multi-container, Docker Compose menyediakan cara yang lebih mudah untuk mengonfigurasi jaringan dan port.
Dalam berkas YAML Docker Compose, Anda dapat menentukan pemetaan port di bawah kunci
portsuntuk setiap layanan:Docker Compose membuat pembedaan penting antara
portsdanexpose. Bagianportsmembuat pemetaan port yang dipublikasikan dan dapat diakses dari luar, sedangkanexposehanya membuat port tersedia bagi layanan yang tertaut dalam jaringan Compose yang sama:Pada contoh ini, layanan
webdapat diakses dari host pada port 8081, tetapi database PostgreSQL hanya dapat diakses oleh layanan lain dalam berkas Compose, tidak langsung dari host.Untuk konfigurasi yang fleksibel, terutama lintas lingkungan yang berbeda, saya dapat menggunakan variabel lingkungan dalam pemetaan port:
Sintaks ini memungkinkan saya menentukan port host melalui variabel lingkungan (
WEB_PORT), dengan default 8081 jika tidak diatur.Mengekspos Port Docker - Contoh Penerapan
Mari kita lalui contoh lengkap mengekspos port Docker untuk aplikasi web dengan backend database.
Bayangkan kita membangun aplikasi web sederhana yang terdiri dari layanan API Python Flask dan database PostgreSQL. Layanan API mendengarkan pada port
5000, dan PostgreSQL menggunakan port defaultnya5432.Berikut tampilan aplikasi Flask sederhana kita (
app.py). Aplikasi ini akan membuat databasemyappdan akan mengambil data dari tabelitems, setelah tabel ini dibuat di dalam database.Selanjutnya, saya akan membuat berkas
requirements.txtkita:Sekarang, saya perlu membuat Dockerfile untuk layanan API Python kita:
Terakhir, saya akan membuat berkas Docker Compose untuk mengorkestrasi kedua layanan:
Dalam konfigurasi ini:
5000, membuatnya dapat diakses dari mesin host.5432tetapi tidak memublikasikannya, sehingga hanya dapat diakses oleh layanan lain dalam jaringan Compose.5432.Untuk menjalankan aplikasi ini, gunakan:
Sekarang, saya dapat mengakses API di
http://localhost:5000, tetapi instance PostgreSQL tidak dapat diakses langsung dari luar jaringan Docker, yang merupakan praktik keamanan yang baik untuk layanan database. Namun Anda dapat mengakses PostgreSQL dari container yang berjalan:Perintah ini akan mengakses CLI PostgreSQL, tempat saya dapat melihat database dan membuat tabel
items. Setelah dibuat, saya dapat melihat datanya dihttp://localhost:5000/itemsCara mengekspos banyak port Docker
Jika aplikasi Python saya perlu mengekspos beberapa port, saya dapat menentukannya semua di Dockerfile:
Dockerfile ini mengekspos:
5000untuk aplikasi Flask utama (saat ini aktif)8081untuk dasbor pemantauan potensial9090untuk antarmuka debugging di masa mendatangPenting untuk dicatat bahwa meskipun saya telah mengekspos port
8081dan9090di Dockerfile sebagai dokumentasi, aplikasi Flask saya saat ini hanya dikonfigurasi untuk mendengarkan pada port5000. Port tambahan yang diekspos menunjukkan di mana fungsionalitas di masa depan mungkin akan diimplementasikan.Cara memublikasikan port yang diekspos
Untuk memublikasikan port yang diekspos dalam Dockerfile, saya menggunakan flag
-patau-Psaat menjalankan container:Ini memetakan port
5000di container (yang diekspos dalam Dockerfile dan tempat Flask mendengarkan) ke port8081di host. Setelah menjalankan perintah ini, saya dapat mengakses aplikasi Flask saya dengan membukahttp://localhost:8081di browser.Saya juga dapat menggunakan flag -P untuk secara otomatis memublikasikan semua port yang diekspos ke port acak di host:
Untuk memeriksa port mana yang dipublikasikan, saya dapat menggunakan:
Untuk informasi yang lebih detail, saya dapat menggunakan:
Perintah ini menampilkan semua pemetaan port untuk container tertentu. Misalnya, jika aplikasi Flask saya hanya mendengarkan pada port
5000tetapi saya telah mengekspos beberapa port di Dockerfile, docker port akan menunjukkan dengan tepat port host mana yang dipetakan ke port container mana. Jadi, jika port5000telah dipetakan ke 32768, saya dapat mengakses aplikasi Flask saya melaluihttp://localhost:32768Teknik Diagnostik dan Pemecahan Masalah
Bahkan dengan konfigurasi yang cermat, masalah dapat terjadi pada pemetaan port Docker. Berikut beberapa teknik yang saya gunakan untuk mendiagnosis dan menyelesaikan masalah umum.
Inspeksi pemetaan port
Langkah pertama dalam mendiagnosis masalah terkait port adalah memverifikasi bahwa pemetaan telah disetel dengan benar. Saya menggunakan perintah berikut:
Daftar semua container yang berjalan beserta pemetaan portnya:
Dapatkan info detail tentang container tertentu:
Periksa pemetaan port untuk container tertentu:
Perintah docker inspect memberikan informasi terperinci, termasuk pengaturan jaringan. Untuk berfokus pada detail terkait jaringan, gunakan:
Jika Anda perlu melakukan analisis trafik yang lebih dalam, alat seperti
tcpdumpdannetstatdapat sangat berguna. Pertama, pastikan alat tersebut terpasang di dalam container. Jika container belum menyertakan alat ini, Anda dapat memasangnya dengan menjalankan perintah berikut:Untuk melihat port mana yang didengarkan aplikasi di dalam container:
Ini menunjukkan, misalnya, bahwa aplikasi Flask mendengarkan pada semua antarmuka di port
5000.Untuk memantau trafik masuk dan keluar pada antarmuka jaringan utama container (biasanya eth0):
Perintah ini memungkinkan Anda menelusuri trafik dan mengidentifikasi apakah permintaan mencapai container atau jika paket dijatuhkan atau salah diarahkan.
Analisis aturan iptables
Docker memanfaatkan
iptablesuntuk mengelola Network Address Translation (NAT) dan mengendalikan aliran trafik antara host dan container. Docker secara otomatis memasukkan aturan untuk meneruskan port host ke IP dan port container yang sesuai, sehingga akses ke layanan dalam container menjadi mulus.Pada host Linux native, Anda dapat memeriksa aturan ini menggunakan perintah seperti:
Ini menunjukkan bagaimana Docker memetakan trafik masuk pada port host tertentu ke endpoint container. Berdasarkan berkas Docker Compose sebelumnya, Anda akan melihat port yang diteruskan:
Berikut penjelasannya:
DNATmengarahkan ulang trafik dari host ke container.RETURNmemastikan routing yang tepat untuk trafik jaringan internal Docker.Namun, bergantung pada lingkungan Anda (misalnya, Docker Desktop di Windows atau WSL2), Docker mungkin menangani penerusan port secara berbeda, dan aturan
iptablesmungkin tidak terlihat atau tidak dapat diubah dari dalam sistem. Dalam kasus ini, Anda dapat memeriksa penerusan port dengan perintah berikut:Tips pemecahan masalah:
docker psdandocker port [container].netstatdantcpdumpuntuk memverifikasi perilaku jaringan aplikasi Anda.Kesimpulan
Mengekspos port Docker adalah keterampilan fundamental yang menjembatani kesenjangan antara isolasi container dan kegunaan praktis. Sepanjang artikel ini, saya telah menjelaskan cara kerja model jaringan Docker, perbedaan antara mengekspos dan memublikasikan port, serta memberikan contoh praktis untuk berbagai skenario.
Ingat poin-poin kunci ini:
EXPOSEdalam Dockerfile untuk mendokumentasikan port yang digunakan aplikasi Anda-patau-Psaat menjalankan container untuk membuat port tersebut dapat diakses dari luarMenguasai konsep dan teknik ini akan memungkinkan Anda merancang aplikasi terkontainerisasi yang lebih tangguh, yang berkomunikasi secara efektif baik secara internal maupun dengan dunia luar. Baik Anda mengembangkan aplikasi web sederhana atau arsitektur microservices yang kompleks, pengelolaan port yang tepat sangat krusial untuk keberhasilan.
Seiring container terus mendominasi strategi penerapan aplikasi modern, kemampuan untuk dengan percaya diri mengelola jaringan dan port Docker akan tetap menjadi keterampilan esensial dalam perangkat kerja setiap pengembang.
Untuk terus belajar, pastikan untuk melihat sumber daya berikut: