You understand the basics, but building an image every time you change a line of code is too slow. In this guide, we will use the modern package manager **uv** to set up our project and **Docker Compose** to create a "mirror" between your computer and the container.

### Step 1: The Setup (Crucial First Steps)

We need to generate the `uv.lock` file locally first. This file ensures that Docker installs the _exact_ same versions of libraries that you have on your machine.

##### 1. Run these commands

Run this in your terminal to initialize the project and generate the lockfile.

```bash
mkdir my-docker-app

cd my-docker-app

# Initialize uv

uv init

# Add Flask (This creates uv.lock!)

uv add flask
```

##### 2. Create app.py

Create this file manually. Note `debug=True` is required for auto-reload.

```python
from flask import Flask

app = Flask(__name__)

@app.route('/')
def hello():
    return 'Hello from Docker!'

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000, debug=True)
```

###### Checkpoint

Before moving to Step 2, look at your folder. Do you see a file named **uv.lock**? Docker needs this file to build successfully!

### Step 2: The "Pure UV" Dockerfile

##### The Dockerfile

We copy the `uv` binary directly into our image. This allows us to install dependencies blazingly fast using the lockfile we generated in Step 1.

```dockerfile
FROM python:3.12-slim

# 1. Install uv directly into the container
COPY --from=ghcr.io/astral-sh/uv:latest /uv /bin/uv

WORKDIR /app

# 2. Copy dependency files FIRST (for caching)

COPY pyproject.toml uv.lock* ./
RUN uv sync --frozen --no-install-project

# Copy your source code
COPY . .
RUN uv sync --frozen

# 4. Copy the rest of the code
COPY . .

CMD ["python", "main.py"]
```

##### Don't forget .dockerignore

Since `uv` creates a local `.venv` folder, we must tell Docker to ignore it to keep the image small.

Create `.dockerignore`:

```
.venv/

__pycache__/

.git/
```

### Step 3: The "Magic" Mirror (Volumes)

This is the configuration that connects VS Code to Docker. We use the `volumes` key to map your folder into the container.

Create a file named **docker-compose.yml**:

```yaml
version: '3.8'

services:
  web-server:
    build: .
    ports:
      - "8080:5000"
    volumes:
      - .:/app  # <--- The Magic Link
```

## Step 4: Control & Shell Access

Your environment is ready. Here is how you control it.

| Goal                                                  | Command                                                              |
|-------------------------------------------------------|----------------------------------------------------------------------|
| **Start (With Hot Reload)**<br>Code changes apply instantly | `docker-compose up -d`                                             |
| **Enter the Shell**<br>Open a terminal _inside_ the running container | `docker-compose exec web-server bash`<br>Once inside, you are in Linux!<br>Type `ls` to see files, or `exit` to leave. |  
| **View Logs**<br>See Python print statements                | `docker-compose logs -f`                                           |
| **Stop Everything**                                      | `docker-compose down`                                              |
