====== Claude Code v Alpine Linux Dockeru ====== Tento setup jsem si chystal pro běh Claude Code v lehkém Alpine Linux kontejneru. Cíl byl jednoduchý: mít persistentní domovský adresář, přístup přes SSH a nemuset po každém rebuildu znovu řešit host klíče nebo přihlašování. ===== docker-compose.yml ===== Služba v ''docker-compose.yml'' vypadá takto: alpine-dev: container_name: alpine-dev build: context: . dockerfile: Dockerfile.alpine-dev restart: "no" networks: - traefik ports: - "4444:22" environment: - TZ=${DOCKER_TZ} volumes: # Domovský adresář - přežije rebuild kontejneru - ${VOLUME_PATH}/alpine-dev:/home/dev stdin_open: true tty: true Důležité body: * ''/home/dev'' je připojený jako volume, takže obsah domovského adresáře přežije rebuild kontejneru. * SSH je vystavené na portu ''4444''. * Kontejner je připravený jako interaktivní dev prostředí, ne jako produkční služba. ===== Dockerfile.alpine-dev ===== FROM alpine:3.23 # Nastavení timezone a locale proměnných ENV TZ=Europe/Prague ENV LANG=cs_CZ.UTF-8 ENV LANGUAGE=cs_CZ:cs ENV LC_ALL=cs_CZ.UTF-8 ENV MUSL_LOCPATH=/usr/share/i18n/locales/musl # Instalace základních balíčků včetně timezone a locale podpory RUN apk add --no-cache \ # Timezone tzdata \ # Locale podpora pro musl musl-locales \ musl-locales-lang \ # Python python3 \ py3-pip \ pipx \ # Node.js (potřeba pro Claude Code) nodejs \ npm \ # Základní nástroje git \ curl \ wget \ jq \ bash \ sudo \ shadow \ openssh-client \ openssh-server \ ca-certificates \ openrc \ # Build nástroje (některé npm balíčky je potřebují) build-base \ && cp /usr/share/zoneinfo/${TZ} /etc/localtime \ && echo "${TZ}" > /etc/timezone # Vytvoření uživatele 'dev' s UID 1000 (pro mapování volumes) RUN addgroup -g 1000 dev && \ adduser -D -u 1000 -G dev -h /home/dev -s /bin/bash dev && \ echo "dev ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/dev && \ chmod 0440 /etc/sudoers.d/dev # Nastavení locale pro bash RUN echo 'export LANG=cs_CZ.UTF-8' >> /etc/profile.d/locale.sh && \ echo 'export LANGUAGE=cs_CZ:cs' >> /etc/profile.d/locale.sh && \ echo 'export LC_ALL=cs_CZ.UTF-8' >> /etc/profile.d/locale.sh && \ chmod +x /etc/profile.d/locale.sh && \ # Pro interactive non-login shells echo 'export LANG=cs_CZ.UTF-8' >> /etc/bash/bashrc && \ echo 'export LANGUAGE=cs_CZ:cs' >> /etc/bash/bashrc && \ echo 'export LC_ALL=cs_CZ.UTF-8' >> /etc/bash/bashrc RUN echo "dev:changeme" | chpasswd # Nastavení pracovního adresáře WORKDIR /home/dev EXPOSE 22 # Přepnutí na uživatele dev #USER dev # Kontejner zůstane běžet #CMD ["tail", "-f", "/dev/null"] #CMD ["/bin/sh", "-c", "ssh-keygen -A && /usr/sbin/sshd -D -e"] CMD ["/bin/sh", "-c", "mkdir -p /home/dev/.ssh/keys && if [ -f /home/dev/.ssh/keys/ssh_host_ed25519_key ]; then cp /home/dev/.ssh/keys/ssh_host_* /etc/ssh/; else ssh-keygen -A && cp /etc/ssh/ssh_host_* /home/dev/.ssh/keys/; fi && /usr/sbin/sshd -D -e"] ===== Jak funguje SSH v tomto setupu ===== Chtěl jsem přístup přes SSH a zároveň jsem nechtěl po každém rebuildu znovu odebírat a přidávat host klíče. Proto start kontejneru dělá toto: * vytvoří adresář ''/home/dev/.ssh/keys'' * pokud už v něm host klíče existují, zkopíruje je do ''/etc/ssh/'' * pokud ještě neexistují, vygeneruje nové přes ''ssh-keygen -A'' a uloží je i do persistentního volume * nakonec spustí ''sshd'' Výsledek: host klíče přežijí rebuild kontejneru a klient SSH nehlásí po každé změně nový fingerprint. ===== Přihlášení přes SSH klíč ===== Do ''/home/dev/.ssh/authorized_keys'' jsem ručně vložil obsah svého veřejného klíče, například ''~/.ssh/id_rsa.pub'', abych se mohl přihlašovat bez hesla. V mém případě se ukázalo, že uživatel ''dev'' musí mít v kontejneru nastavené heslo, jinak SSH přihlášení klíčem nefungovalo spolehlivě. Proto je v Dockerfile tento řádek: echo "dev:changeme" | chpasswd Heslo ''changeme'' je dobré po prvním spuštění změnit, ale běžně se nepřihlašuji heslem. Prakticky používám přístup pouze přes SSH klíč. Přihlášení pak může vypadat například takto: ssh dev@localhost -p 4444 ===== Práva pro .ssh a authorized_keys ===== Pokud jsou práva moc volná, ''sshd'' může soubor ''authorized_keys'' ignorovat. Osvědčené nastavení je: mkdir -p /home/dev/.ssh chmod 700 /home/dev/.ssh chmod 600 /home/dev/.ssh/authorized_keys chown -R dev:dev /home/dev/.ssh Tohle je potřeba zkontrolovat hlavně tehdy, když je ''/home/dev'' připojený jako volume a soubory vznikly mimo kontejner nebo pod jiným UID. ===== .profile a .bashrc ===== Musel jsem si upravit i shell init soubory. ''.profile'': [ -f ~/.bashrc ] && . ~/.bashrc ''.bashrc'': export PATH="$HOME/.local/bin:$PATH" První řádek zajistí načtení ''~/.bashrc''. Druhý přidá do ''PATH'' uživatelské binárky, typicky kvůli nástrojům instalovaným přes ''pipx''. ===== Shrnutí ===== Tento Alpine kontejner řeší pro Claude Code hlavně tři věci: * lehké dev prostředí s Node.js, Pythonem a běžnými CLI nástroji * persistentní ''/home/dev'' napojený přes volume * stabilní SSH přístup s přihlášením přes klíč a zachováním host klíčů mezi rebuildy