Don’t want to read through all this?
Just point any AI chat (Claude, ChatGPT, etc.) to this page in Markdown or to the 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 or Mac Docker Desktop guides for platform-specific setup instructions.
I’ve got two Docker images: xedant/code:dev-latest and xedant/code:min-latest.
Dev image (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 (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.
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 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.