---
title: "Docker Setup"
id: "139"
type: "page"
slug: "docker"
published_at: "2026-05-09T13:52:58+00:00"
modified_at: "2026-06-09T14:05:20+00:00"
url: "https://xedant.com/code/docker"
markdown_url: "https://xedant.com/code/docker.md"
excerpt: "Docker enables full isolation of development environment for each project. Even when models misbehave, they…"
---

# Docker Setup

[https://xedant.com/code/docker.md](https://xedant.com/code/docker.md)

Don’t want to read through all this? Just point any AI chat (Claude, ChatGPT, etc.) to [this page in Markdown](https://xedant.com/code/docker.md)
 or to the [llms.txt](/llms.txt)
 index, and ask it to generate the config files and commands for you. It’ll read the docs, ask you a few questions about your setup, and give you ready-to-use configuration. Save your time — let the model do the reading.

 You could also contact me via Telegram — I’m always eager to help. I’m not being just polite here — I really like to chat with like-minded people, especially if you love coding as much as I do.

 Docker enables full isolation of development environment for each project. Even when models misbehave, they could damage their container only. Recreating and restarting it takes few seconds. It also enables to add project-specific tools and configuration instead of bloating universal image.

**Docker Desktop users:** If you prefer a graphical interface for Docker, see the [Windows Docker Desktop](/code/windows-docker-desktop)
 or [Mac Docker Desktop](/code/mac-docker-desktop)
 guides for platform-specific setup instructions.

I’ve got two Docker images: [xedant/code:dev-latest](https://hub.docker.com/repository/docker/xedant/code/tags/dev-latest)
 and [xedant/code:min-latest](https://hub.docker.com/repository/docker/xedant/code/tags/min-latest)
.

[Dev image](https://hub.docker.com/repository/docker/xedant/code/tags/dev-latest)
 (2.8Gb) contains Xedant Code with tools required for its development and building – ASP.NET Core dev and Node.js with building and linting tools. You could use it if you develop client/server apps in ASP.NET Core and Node.js as a frontend.

What’s included in the dev image - **ASP.NET Core 9.0 SDK** — build and run .NET applications
- **Node.js (LTS)** — JavaScript runtime with npm
- **Python 3** — interpreter with pip and venv
- **Claude Code CLI** — AI coding agent
- **dotnet-ef** — Entity Framework Core migrations
- **JetBrains ReSharper CLI** — .NET code inspection and cleanup
- **flake8** — Python linter
- **Docker + Docker Compose** — container management from within the container
- **git** — version control
- **mc** — Midnight Commander file manager
- **ncdu** — disk usage analyzer
- **sqlite3** — database CLI
- **curl, wget, rsync, zip, unzip** — networking and file utilities

 [Minimal image](https://hub.docker.com/repository/docker/xedant/code/tags/min-latest)
 (570 Mb) contains Xedant Code with Python and all required tools. It’s a full-featured image for projects that don’t use ASP.NET Core — significantly smaller while still providing everything Claude Code needs out of the box. You could further extend it with your development environment on demand, by asking models to install missing packages. Or build your custom Docker image based on it that best fits your needs. Please contact me if you need help with that.

What’s included in the minimal image - **ASP.NET Core 9.0 Runtime** — run .NET applications (no SDK for building)
- **Node.js (LTS)** — JavaScript runtime with npm
- **Python 3** — interpreter with pip and venv
- **Claude Code CLI** — AI coding agent
- **flake8** — Python linter
- **Docker + Docker Compose** — container management from within the container
- **git** — version control
- **mc** — Midnight Commander file manager
- **ncdu** — disk usage analyzer
- **sqlite3** — database CLI
- **curl, wget, rsync, zip, unzip** — networking and file utilities

 I plan to release framework-specific images in the future, you just need to contact me via Telegram and tell what stack do you use, then I could build and support them further. It’s really not hard for me to design and support more frameworks and development environments, I just need to know what you are actually using.

## Extending the Image with Custom Tools

Both images come with all the tools Claude Code needs to work. But if your project uses specific languages or tools, you can build a custom image on top of `xedant/code:min-latest` that includes exactly what you need. This way every new container starts with your tools pre-installed instead of installing them on every recreate.

### Creating a Custom Dockerfile

Create a `Dockerfile` next to your `docker-compose.yml`:

```
FROM xedant/code:min-latest

# Add system packages
RUN apt-get update && apt-get install -y \
    ruby \
    default-jdk \
    && rm -rf /var/lib/apt/lists/*

# Add Python packages
RUN python3 -m pip install --break-system-packages \
    fastapi \
    pytest

# Add Node.js packages (Node.js is pre-installed in min image)
RUN npm install -g \
    typescript \
    @angular/cli

# Add global tools
RUN dotnet tool install -g Your.Tool.Name
```

Then update your `docker-compose.yml` to use your custom image instead of the pre-built one:

```
services:
  my_project:
    container_name: my_project
    build: .                    # builds from Dockerfile in this directory
    image: my-project:latest    # tag for the built image
    ports:
      - "5001:80"
    volumes:
      - "./MyProject:/project"
    environment:
      - XEDANT_CODE_LOGIN=code
# ... rest of your environment variables
    restart: unless-stopped
    working_dir: /app
```

Build and start your custom image:

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

The `--build` flag rebuilds your custom image if the Dockerfile changed. Without it, Docker reuses the last build.

### Or Just Ask the Model

If you don’t want to bother with Dockerfiles, you can just ask Claude Code to install packages inside the running container. It has `sudo` access and can install anything with `apt`, `pip`, or `npm`. The downside is these installations are lost when the container is recreated — building a custom image makes them permanent.

```
services:  
  xedant_code_demo: # rename it according to your project name
    container_name: xedant_code_demo # rename it according to your project name
    image: xedant/code:dev-latest
    ports:
      - "5001:80"      
    volumes:
      - "./DemoProject:/project" # replace ./DemoProject with the folder with your project
    environment:      
      - XEDANT_CODE_LOGIN=code
      - XEDANT_CODE_PASSWORD=5694d08a2e53ffcae0c3103e5ad6f6076abd960eb1f8a56577040bc1028f702b # sha256 hash code for password `code`
      - JWT_SECRET_KEY= # must be a unique, hard-to-guess random string (at least 32 characters). Anyone who knows this key can generate valid authentication tokens. If omitted, a key is auto-generated but lost when the container is recreated, forcing all users to relogin
      - ASPNETCORE_ENVIRONMENT=Production
      - ASPNETCORE_URLS=http://+:80 # port inside the container
      - XEDANT_CODE_PROJECT_PATH=/project # path to the project inside the container
      - XEDANT_CODE_GIT_USER_NAME=User # your name for git commits
      - XEDANT_CODE_GIT_USER_EMAIL=me@gmail.com # your email for git commits
      - XEDANT_CODE_PROJECT_GIT_URL=https://github.com/Xedant/DemoProject.git # replace it with your project git url
      - XEDANT_CODE_PROJECT_GIT_LOGIN= # your git login
      - XEDANT_CODE_PROJECT_GIT_PASSWORD= # your git personal access key
      - XEDANT_CODE_SKILLS_GIT_URL=https://github.com/Xedant/DemoSkills.git # replace it with your skills git url
      - XEDANT_CODE_SKILLS_GIT_LOGIN= # your git login
      - XEDANT_CODE_SKILLS_GIT_PASSWORD= # your git personal access key
# optional: storing data in Postgres, not in local SQLite. It's recommended to have separate databases for each of your projects.
# - XEDANT_CODE_DATABASE=Server=postgres;Port=5433;User Id=code;Password=code;Database=code;Pooling=false;Timeout=600;CommandTimeout=600;KeepAlive=600;
# optional: pushing chat stats into Clickhouse for visualizing in Grafana
# - XEDANT_CODE_CLICKHOUSE_URL=Host=clickhouse;Port=8127;Protocol=http;Database=code;Username=code;Password=code
# optional: your license key if you have one
# - XEDANT_CODE_LICENSE=
    restart: unless-stopped
    working_dir: /app
```

## Docker CLI with .env file

You can also run Xedant Code directly with the `docker run` command, storing environment variables in a `.env` file. This avoids putting secrets in your compose file or on the command line.

Create a `.env` file next to your project folder:

```
# .env
XEDANT_CODE_LOGIN=code
XEDANT_CODE_PASSWORD=5694d08a2e53ffcae0c3103e5ad6f6076abd960eb1f8a56577040bc1028f702b
JWT_SECRET_KEY=
ASPNETCORE_ENVIRONMENT=Production
ASPNETCORE_URLS=http://+:80
XEDANT_CODE_PROJECT_PATH=/project
XEDANT_CODE_GIT_USER_NAME=User
XEDANT_CODE_GIT_USER_EMAIL=me@gmail.com
XEDANT_CODE_PROJECT_GIT_URL=https://github.com/Xedant/DemoProject.git
XEDANT_CODE_PROJECT_GIT_LOGIN=
XEDANT_CODE_PROJECT_GIT_PASSWORD=
XEDANT_CODE_SKILLS_GIT_URL=https://github.com/Xedant/DemoSkills.git
XEDANT_CODE_SKILLS_GIT_LOGIN=
XEDANT_CODE_SKILLS_GIT_PASSWORD=
```

Then launch the container:

```
docker run -d \
  --name xedant_code_demo \
  --env-file .env \
  -p 5001:80 \
  -v ./DemoProject:/project \
  --restart unless-stopped \
  -w /app \
  xedant/code:dev-latest
```

The `--env-file` flag reads all variables from the file. You can override individual values by adding extra `-e` flags after it, for example `-e XEDANT_CODE_LICENSE=your-key`.

## Auto-Generated Credentials

If you omit the `XEDANT_CODE_LOGIN` and `XEDANT_CODE_PASSWORD` environment variables, the application generates temporary credentials on startup. The login is `code` and a random password is printed to the container’s console output. View it with:

```
docker logs xedant_code_demo
```

These credentials are valid until the container restarts. The login page will show a notice about temporary credentials and prompt you to set permanent ones via [environment variables](/code/docs/environments)
.

## Generating a Password Hash

The `XEDANT_CODE_PASSWORD` variable must contain a **SHA256 hash** of your desired password, not the plaintext password itself. The login page has a built-in SHA256 generator — click the *“▸ SHA256 generator”* link below the Sign In button. It runs entirely client-side: enter a password, copy the hash, and paste it into your environment configuration.

## Security Best Practices

The `.xedant/environments.yml` file inside your project is meant to be committed to git so it’s available on every setup. To avoid committing secrets (API keys, license keys, etc.) into version control, provide them as environment variables on the Docker container and reference them by name using the `$VARIABLE_NAME` syntax in `environments.yml`. See the [Environments](/code/docs/environments)
 page for the full list of available variables and how they work:

```
# .xedant/environments.yml
environments:
  production:
    variables:
      API_KEY: $MY_API_KEY          # resolved from the container's environment at runtime
      LICENSE_KEY: $MY_LICENSE_KEY   # not committed to git
      PUBLIC_URL: https://example.com # non-sensitive values are fine to commit directly
```

This way the actual secret values stay in your Docker environment configuration (compose file, `.env`, or `-e` flags) while `environments.yml` remains safe to commit.
