Coder
lastmod 2026-09-14created 2026-05-3110 edits
Secure environments for developers and their agents
Tutorials
- Coder:HowToUse - Explains the basic way to connect
Install
Docker
## 1. 공식 compose 예제 다운로드 / Download the official compose example
curl -fLo compose.yaml https://raw.githubusercontent.com/coder/coder/main/compose.yaml
## 2. docker 그룹 GID 확인 (아래 group_add 값에 사용) / Get docker group GID
getent group docker | cut -d: -f3
## 3. Coder 기동 / Start Coder
docker compose up -d
## 4. 로그 확인 (access URL 확인용) / Check logs for the access URL
docker compose logs -f coder
An externally reachable IP or domain must be set in the CODER_ACCESS_URL environment variable.
Client login
## 클라이언트 설치
curl -fsSL https://coder.com/install.sh | sh
## `coder` 커맨드 사용 가능
coder login https://coder.run # 브라우저가 열리고 세션 토큰 발급 / opens browser for session token
How to connect via SSH
After creating a workspace:
Attaching a GPU to a Docker template
Just modify the template:
Since kreuzwerker/docker is in use, the gpus argument is available as-is on docker_container. It is converted into DeviceRequests, the same as docker run --gpus all.
resource "docker_container" "workspace" {
count = data.coder_workspace.me.start_count
image = docker_image.main.image_id
name = "coder-${data.coder_workspace_owner.me.name}-${lower(data.coder_workspace.me.name)}"
gpus = "all" # == docker run --gpus all
# ...
}
Increasing shared memory in a Docker template
Just modify the template:
The docker_container of kreuzwerker/docker has a shm_size argument. The unit is MB, and it behaves the same as docker run --shm-size=10g.
resource "docker_container" "workspace" {
count = data.coder_workspace.me.start_count
image = "coder-dgx-spark:cuda13"
name = "coder-${data.coder_workspace_owner.me.name}-${lower(data.coder_workspace.me.name)}"
gpus = "all"
shm_size = 10240 # == docker run --shm-size=10g (MB 단위)
# ...
}
Changing shm_size causes the container to be recreated, so the workspace must be restarted. The home directory is in home_volume, so data is preserved.
After applying, check inside the container:
If Size shows 10G, it is working. /dev/shm is tmpfs, so it only occupies as much RAM as is actually used.
=== Note: ipc_mode = "host" === If you want to remove the limit entirely, you can use ipc_mode = "host" instead of shm_size. However, it shares the host IPC namespace, which weakens isolation. shm_size, which explicitly limits the size, is recommended.
Troubleshooting
HTTP 400: System message must be at the beginning
After running vLLM, connecting AI as "OpenAI compatible" fails with HTTP 400 and prints the following error:
The Jinja chat template is the problem.
Many templates contain defensive code like this:
{%- if messages[0]['role'] != 'system' and ns.system_seen %}
{{- raise_exception('System message must be at the beginning') }}
{%- endif %}
That is, role: "system" appeared in the messages array at a position other than the first. Either the gateway inserted an extra system message while passing the prompt through, or the client sent a system message again in the middle of the conversation.
Common causes:
- Anthropic-format client (Claude Code, etc.) → OpenAI-format conversion. In Anthropic,
systemis a separate top-level field, so its position can get misaligned during conversion. - The agent harness inserts a system reminder in the middle of the conversation (Claude Code and Cline often do this)
- Two or more system messages (the first is fine, but the second is in the middle)
- Mapping
role: "developer"to system shifts the position
See also
- VSCode
- Cloud9
- Jupyter
- Gitpod
- Eclipse Che
- DevPod (Loft Labs)
- OpenVSCode Server / code-server