# Running Meezi fully in Docker

## Quick start

```powershell
cd F:\Projects\Meezi
copy .env.example .env   # if not done yet
powershell -File scripts\docker-up-full.ps1
```

Or manually:

```powershell
docker compose up -d --build
```

| Service    | URL |
|-----------|-----|
| Dashboard | http://localhost:3101/fa/login |
| API       | http://localhost:5080/swagger |
| Health    | http://localhost:5080/health |

Demo OTP phone: `09121234567`

## If API build fails pulling .NET images

Default bases are **MCR** (official):

- `mcr.microsoft.com/dotnet/sdk:10.0`
- `mcr.microsoft.com/dotnet/aspnet:10.0`

Override in `.env` if needed:

```env
DOTNET_SDK_IMAGE=mcr.microsoft.com/dotnet/sdk:10.0
DOTNET_ASPNET_IMAGE=mcr.microsoft.com/dotnet/aspnet:10.0
```

### `insufficient_scope` / `pull access denied` on `docker.io/dotnet/sdk:10.0`

That usually means **Docker Hub auth**, not a missing .NET 10 tag. Do **not** rely on `dotnet/sdk:10.0` on Docker Hub unless pulls work on your machine.

1. **Clear bad Hub login** (fixes many `insufficient_scope` errors):

   ```powershell
   docker logout
   docker pull mcr.microsoft.com/dotnet/sdk:10.0
   docker pull mcr.microsoft.com/dotnet/aspnet:10.0
   ```

2. **VPN** — then pre-pull MCR and build:

   ```powershell
   docker pull mcr.microsoft.com/dotnet/sdk:10.0
   docker pull mcr.microsoft.com/dotnet/aspnet:10.0
   docker compose up -d --build
   ```

3. **Registry mirror** — Docker Desktop → Settings → Docker Engine, merge [`docker/daemon-registry-mirror.example.json`](../docker/daemon-registry-mirror.example.json), Apply & Restart.

4. **Pre-pull all images with VPN**, then build offline:

   ```powershell
   docker pull mcr.microsoft.com/dotnet/sdk:10.0
   docker pull mcr.microsoft.com/dotnet/aspnet:10.0
   docker pull postgres:16-alpine
   docker pull redis:7-alpine
   docker pull node:20-alpine
   docker compose up -d --build
   ```

## NuGet restore fails inside Docker (`SSL_ERROR_SSL`, `bad record mac`)

Example during `dotnet restore`:

```text
Failed to download package 'Microsoft.CodeAnalysis.CSharp.4.14.0' from 'https://api.nuget.org/...'
Decrypt failed with OpenSSL error - SSL_ERROR_SSL
error:0A000119:SSL routines::decryption failed or bad record mac
```

This is **not a Meezi code bug** — TLS to `api.nuget.org` is being corrupted or cut off inside the build container (unstable VPN, antivirus HTTPS scan, filtered ISP, Docker Desktop network glitch).

**Try in order:**

1. **Restart Docker Desktop** fully (Quit → start again). After `Ctrl+C` mid-build, the engine often returns `500 Internal Server Error` until restarted.

2. **VPN on** for the whole build (connect *before* `docker compose build`, keep it on until restore finishes).

3. **Pre-restore on the host** (uses Windows network, often more reliable), then rebuild:

   ```powershell
   cd F:\Projects\Meezi
   dotnet restore src\Meezi.API\Meezi.API.csproj
   docker compose build api
   docker compose up -d
   ```

4. **Disable HTTPS inspection** in antivirus / corporate proxy for Docker Desktop and `docker.exe`.

5. **Retry** — `docker compose build api --no-cache` once network is stable.

The API `Dockerfile` uses `nuget.config` retries, `NUGET_CERT_REVOCATION_MODE=offline`, and a NuGet cache mount to make repeat builds easier.

## Docker Desktop `500 Internal Server Error` on `docker compose up`

```text
unable to get image 'meezi-web': request returned 500 Internal Server Error
... dockerDesktopLinuxEngine ...
```

The Linux engine crashed or is stuck (common after aborting a long build).

```powershell
# 1) Quit Docker Desktop from the tray (not only close the window)
# 2) Optional — reset WSL backend (Docker Desktop → WSL2):
wsl --shutdown
# 3) Start Docker Desktop, wait until it says "Running"
docker version
docker compose build
docker compose up -d
```

If `docker version` hangs, Docker is still broken — reboot Windows or **Troubleshoot → Reset to factory defaults** in Docker Desktop (last resort).

## Why the API image does not run `apt-get`

Older Dockerfiles installed `curl` for healthchecks, which downloads Ubuntu packages during **build** (`archive.ubuntu.com`). That often fails in Iran without VPN.

The API image now uses a **TCP healthcheck** on port 8080 instead — no extra OS packages.

## Commands

```powershell
docker compose ps
docker compose logs -f api
docker compose down
docker compose down -v   # also removes DB volume
```

## Infra-only fallback (host API)

Only if Docker cannot build .NET images at all:

```powershell
docker compose up -d postgres redis
cd src\Meezi.API
$env:RUN_MIGRATIONS="true"
dotnet run
```
