code-server — VS Code w przeglądarce na własnym serwerze
code-server uruchamia VS Code na Twoim serwerze i podaje go przez przeglądarkę — z terminalem, gitem i rozszerzeniami. Pokazujemy instalację, config.yaml z hasłem w argonie, wystawienie przez Caddy i Nginx, wbudowany proxy portów przy Laravel Sailu oraz to, czego nie da się obejść: brak marketplace’u Microsoftu, jedno hasło na instancję i konieczność życia na najnowszym wydaniu.
code-server uruchamia VS Code jako usługę na serwerze i podaje jego interfejs przez przeglądarkę. Nie jest to podglądacz plików ani okrojony edytor: dostajesz pełny workbench z terminalem, gitem, debuggerem i rozszerzeniami, tylko renderowany w karcie przeglądarki, a proces edytora działa na maszynie, na której leży kod. Repozytorium coder/code-server ma 78,9 tysiąca gwiazdek i 6812 forków, powstało w lutym 2019 roku, jest na licencji MIT, a wydanie 4.133.0 wyszło 17 sierpnia 2026 i nadąża za Code 1.133.0.
Tempo wydań to jedna nowa wersja na tydzień, wypuszczana kilka dni po odpowiadającym jej wydaniu VS Code. Projekt jest sponsorowany przez firmę Coder i to widać w kadencji: 4.132.0 z 10 sierpnia, 4.131.0 z 30 lipca, 4.130.0 z 23 lipca. Bieżąca linia działa już na Node.js 24.
Piszemy o nim, bo w pracy agencyjnej powtarza się kilka sytuacji, w których edytor musi być tam, gdzie kod, a nie tam, gdzie laptop: serwer klienta, do którego nie wolno kopiować repozytorium, maszyna z 64 GB RAM-u i lokalnym Dockerem, środowisko staging, w którym trzeba coś podejrzeć z telefonu albo iPada. code-server rozwiązuje dokładnie to. Ma jednak ograniczenia, których nie da się przekonfigurować, i o nich też piszemy — bo decyzja o wdrożeniu tego narzędzia w zespole opiera się w praktyce na nich, nie na liście funkcji.
Czym code-server jest, a czym nie jest
code-server to fork VS Code utrzymywany patchami. Upstream jest wciągany jako submoduł, a zmiany trzymane osobno jako łatki, dzięki czemu aktualizacja do kolejnego wydania Code sprowadza się do przełożenia patchy. Konsekwencja jest ważniejsza, niż wygląda: budowany jest Code — OSS, czyli otwarty rdzeń, a nie firmowa kompilacja Microsoftu. To rdzeń otwarty, ale nie identyczny z tym, co pobierasz ze strony VS Code, i różnica ujawnia się przy rozszerzeniach.
code-server, VS Code Web, OpenVSCode Server i Codespaces
Cztery rzeczy, które robią pozornie to samo:
- VS Code Web (
code serve-web) — oficjalne rozwiązanie Microsoftu. Jedyny wariant z legalnym dostępem do marketplace’u Microsoftu, więc jeśli potrzebujesz Copilota albo rozszerzeń Remote Development, wybór jest wymuszony. - OpenVSCode Server — fork z commitami wnoszonymi wprost do drzewa VS Code, o zakresie ograniczonym do „udostępnij VS Code w przeglądarce takim, jaki jest”. Bez dodatków pod self-hosting.
- GitHub Codespaces — usługa zamknięta i płatna, z rozliczaniem czasu maszyny.
- code-server — self-hosted, MIT, z warstwą rzeczy potrzebnych przy własnym hostingu: uwierzytelnianie hasłem, serwowanie z podścieżki, wbudowany proxy do portów maszyny wpięty w panel Ports, ustawienia trzymane na dysku jak w desktopowym VS Code (a nie w pamięci przeglądarki), webviews niewołające serwerów Microsoftu, możliwość podstawienia własnego marketplace’u i własnej telemetrii, osobny proces nadzorczy z własnym CLI.
Ta lista różnic jest jednocześnie odpowiedzią na pytanie „czemu nie po prostu code serve-web”: przy self-hostingu potrzebujesz właśnie tych rzeczy, a nie ich brakuje w wariancie oficjalnym z powodów, które prawdopodobnie się nie zmienią.
code-server a Coder
Warto to rozdzielić, bo nazwy są mylące. code-server to jedna instancja edytora dla jednej osoby. Coder (repozytorium coder/coder) to platforma do provisionowania środowisk deweloperskich Terraformem, w której code-server jest jedną z aplikacji uruchamianych w workspace’ie. Jeśli szukasz rozwiązania dla dziesięciu osób z kontrolą dostępu i zasobów, właściwym narzędziem jest Coder albo własna orkiestracja kontenerów — nie druga instancja code-servera na tym samym porcie.
Kiedy to ma sens
Z naszej praktyki wychodzą cztery scenariusze, w których code-server wygrywa z lokalnym edytorem i tunelem SSH:
- Kod nie może zjechać na laptopa. Umowa z klientem albo polityka bezpieczeństwa mówi, że repozytorium zostaje na ich infrastrukturze. Edytor idzie wtedy do kodu, nie odwrotnie.
- Środowisko jest za duże na laptopa. Projekt z kilkunastoma kontenerami, indeksem Elasticsearcha i zrzutem produkcyjnej bazy pracuje na maszynie w chmurze, a nie na MacBooku z 16 GB pamięci.
- Dostęp z urządzenia bez klienta SSH. iPad, cudzy komputer, telefon przy awarii. To jedyna sytuacja, w której tunel SSH nie wystarczy.
- Wspólne środowisko do debugowania. Jedna maszyna, jedno ustawione środowisko, cały zespół widzi te same logi i tę samą bazę bez „u mnie działa”.
Wymagania sprzętowe są niskie: producent podaje minimum 1 GB RAM-u i 2 rdzenie, a przy VM-ce w chmurze zaleca 2 GB i dysk SSD od 32 GB. Realnie liczy się to, co uruchomisz obok — sam edytor mieści się w tym budżecie, ale Sail z Postgresem już nie.
Środowisko musi przepuszczać WebSockety. Cała komunikacja przeglądarki z serwerem na nich stoi i to pierwsza rzecz do sprawdzenia, gdy interfejs ładuje się do połowy i zamiera.
Instalacja
install.sh
Skrypt instalacyjny wykrywa system i sięga po menedżer pakietów, a gdy go nie ma — rozpakowuje wydanie standalone do ~/.local. Przed uruchomieniem opłaca się zobaczyć, co zrobi:
curl -fsSL https://code-server.dev/install.sh | sh -s -- --dry-runPotem to samo bez --dry-run. Przydatne flagi: --method=standalone (wymuszenie archiwum zamiast pakietu), --prefix=/usr/local (instalacja systemowa), --version=X.Y.Z (konkretna wersja, przydatne przy odtwarzaniu środowiska), --edge (wydanie przedpremierowe).
Pakiety systemowe i systemd
Na Debianie i Ubuntu wchodzi paczka .deb, na Fedorze i RHEL-u .rpm, na Arch Linuksie pakiet z AUR, na macOS formuła Homebrew. W każdym z tych wariantów usługę uruchamia szablon systemd sparametryzowany użytkownikiem:
curl -fOL https://github.com/coder/code-server/releases/download/v4.133.0/code-server_4.133.0_amd64.deb
sudo dpkg -i code-server_4.133.0_amd64.deb
sudo systemctl enable --now code-server@$USERZapis code-server@$USER to nie ozdoba składniowa: instancja działa z uprawnieniami tego użytkownika i widzi jego katalog domowy, jego klucze SSH i jego konfigurację. Uruchomienie tego jako root oznacza, że każdy, kto zdobędzie hasło do panelu, ma roota na maszynie.
Wydania systemowe są publikowane dla amd64 i arm64. Dla Windows nie ma wydań i nie zapowiada się na zmianę.
npm i standalone
Instalacja przez npm jest ścieżką dla przypadków, w których gotowe archiwum nie zadziała: architektura inna niż amd64 i arm64, Alpine Linux i inne systemy bez glibc, glibc starsze niż 2.28 albo glibcxx starsze niż 3.4.21. Kompilują się wtedy moduły natywne, więc potrzebne są zależności C. Na Raspberry Pi producent też zaleca npm.
Archiwum standalone niesie własne Node i moduły, wystarczy je rozpakować i uruchomić ./bin/code-server. To najprostszy sposób trzymania kilku wersji obok siebie.
Docker
Oficjalny obraz to codercom/code-server, w wariantach na Debiana (trixie), Ubuntu (resolute) i Fedorę, dla amd64 i arm64. Tagi latest, 4.133.0 i 4.133.0-trixie odświeżone 17 sierpnia 2026. Dla arm32 zostaje obraz społecznościowy linuxserver/code-server.
mkdir -p ~/.config
docker run -it --name code-server -p 127.0.0.1:8080:8080 \
-v "$HOME/.local:/home/coder/.local" \
-v "$HOME/.config:/home/coder/.config" \
-v "$PWD:/home/coder/project" \
-u "$(id -u):$(id -g)" \
-e "DOCKER_USER=$USER" \
codercom/code-server:latestDwie rzeczy w tym poleceniu są istotne. -p 127.0.0.1:8080:8080 wiąże port tylko z pętlą lokalną — bez tego kontener wystawia edytor na wszystkie interfejsy maszyny. A -u "$(id -u):$(id -g)" sprawia, że pliki tworzone w kontenerze mają Twojego właściciela; pominięcie tego kończy się katalogiem vendor należącym do obcego UID-a.
Jest też chart Helma w repozytorium (ci/helm-chart, wersja 3.48.0 z obrazem 4.133.0). Nie jest publikowany do żadnego repozytorium chartów — trzeba sklonować projekt i zainstalować z katalogu:
git clone https://github.com/coder/code-server
cd code-server
helm upgrade --install code-server ci/helm-chartChart jest utrzymywany przez społeczność, domyślnie zakłada wolumen 1 Gi i wyłączony ingress. Dokumentacja docs/helm.md ma nieodświeżone plakietki (obiecuje wersję 1.0.0 i obraz 4.8.0) — wartości bierz z values.yaml, nie z README.
Konfiguracja: config.yaml
Przy pierwszym starcie powstaje ~/.config/code-server/config.yaml z wygenerowanym losowo hasłem:
bind-addr: 127.0.0.1:8080
auth: password
password: mew...22
cert: falseKażdy klucz w tym pliku odpowiada jednej fladze CLI — code-server --help jest więc pełną listą opcji konfiguracji. Flagi przekazane w linii poleceń mają priorytet nad plikiem. Lokalizację pliku zmienia --config albo $CODE_SERVER_CONFIG, a domyślna respektuje $XDG_CONFIG_HOME.
Domyślne bind-addr na 127.0.0.1 jest świadome: świeża instalacja nie jest widoczna z sieci, dopóki sam tego nie zmienisz. Uwierzytelnianie hasłem ma limit prób — dwie na minutę plus dwanaście na godzinę. To nie zabezpieczenie, tylko hamulec na skanery; słabe hasło i tak padnie, tylko wolniej.
Hasło w postaci hasha
Hasło w czystym tekście w pliku konfiguracyjnym jest tym, czym wygląda. Zamiast password ustaw hashed-password z hashem argona:
echo -n "twoje-haslo" | npx argon2-cli -eauth: password
hashed-password: "$argon2i$v=19$m=4096,t=3,p=1$wST5QhBgk2lu1ih4DMuxvg$LS1alrVdIWtvZHwnzCM1DUGg+5DTO3Dt1d5v9XtLws4"hashed-password ma pierwszeństwo nad password. Cudzysłowy są obowiązkowe. A jeśli hash idzie przez docker-compose.yml w zmiennej HASHED_PASSWORD, każdy pojedynczy $ trzeba podwoić do $$ — inaczej Compose potraktuje fragmenty hasha jako zmienne i podstawi puste ciągi. Objaw: hasło przestaje pasować bez żadnego komunikatu o błędzie.
Wystawianie na świat
Tu jest miejsce na jedno zdanie, które trzeba przeczytać dosłownie, bo cała reszta sekcji z niego wynika.
code-server daje przez przeglądarkę terminal na serwerze. Instancja bez uwierzytelnienia i bez szyfrowania to nie „edytor bez hasła” — to zdalne wykonywanie kodu wystawione na publiczny adres. Traktuj ją jak dostęp SSH, bo dokładnie tym jest.
Tunel SSH
Najbezpieczniejszy i najprostszy wariant, jeśli nie potrzebujesz dostępu z iPada. Na serwerze wyłączasz uwierzytelnianie w edytorze (bo warstwę uwierzytelnienia daje już SSH), zostawiasz nasłuch na pętli lokalnej i przekierowujesz port:
sed -i.bak 's/auth: password/auth: none/' ~/.config/code-server/config.yaml
sudo systemctl restart code-server@$USER# -N nie uruchamia zdalnej powłoki
ssh -N -L 8080:127.0.0.1:8080 deploy@10.20.0.14Edytor jest wtedy pod http://127.0.0.1:8080 — czyli w kontekście uznawanym przez przeglądarkę za bezpieczny, co ma znaczenie przy webviews (o tym niżej). Do wychwytywania zerwanych tuneli warto dopisać w ~/.ssh/config:
Host *
ServerAliveInterval 5
ExitOnForwardFailure yesDo tunelu można też przekazać agenta SSH i agenta GPG, dzięki czemu commity z serwera są podpisane Twoim kluczem, a klucz nie leży na cudzej maszynie.
Caddy
Gdy potrzebujesz dostępu z przeglądarki bez tunelu, najkrótsza droga do certyfikatu z Let's Encrypt to Caddy. Cały Caddyfile:
code.example.com {
reverse_proxy 127.0.0.1:8080
}Wariant z podścieżką, jeśli domena jest już zajęta przez coś innego:
code.example.com/code/* {
uri strip_prefix /code
reverse_proxy 127.0.0.1:8080
}Nginx
Na Nginksie konfiguracja jest dłuższa i ma jedną pułapkę — bez nagłówków Upgrade i Connection WebSockety nie przejdą, a edytor będzie się ładował w nieskończoność:
server {
listen 80;
listen [::]:80;
server_name code.example.com;
location / {
proxy_pass http://localhost:8080/;
proxy_set_header Host $http_host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection upgrade;
proxy_set_header Accept-Encoding gzip;
}
}Certyfikat dokłada certbot:
sudo certbot --non-interactive --redirect --agree-tos --nginx -d code.example.com -m biuro@example.comcode-server potrafi też sam obsłużyć TLS — --cert bez argumentu generuje certyfikat samopodpisany do ~/.local/share/code-server/self-signed.crt, a --cert ze ścieżką plus --cert-key podstawia własny. Wtedy ruch HTTP jest przekierowywany na HTTPS. Nasłuch na porcie 443 bez roota wymaga nadania uprawnienia binarce Node:
sudo setcap cap_net_bind_service=+ep /usr/lib/code-server/lib/nodeCertyfikaty samopodpisane traktuj jako ostatnią opcję: nie działają na iPadzie i powodują trudne do zdiagnozowania problemy. Jeśli musisz, użyj mkcert, żeby certyfikat był zaufany w systemie.
Uwierzytelnianie zewnętrzne
Jedno hasło na instancję to model wystarczający dla jednej osoby i za słaby dla firmy. Logowania kontem służbowym code-server sam nie obsługuje — trzeba postawić przed nim odwrotne proxy, które to zrobi: oauth2-proxy, Pomerium albo Cloudflare Access. W naszej praktyce równie dobrze zdaje egzamin schowanie instancji w sieci WireGuard i wystawienie jej wyłącznie tam; wtedy uwierzytelnianie w edytorze jest drugą warstwą, a nie jedyną.
Przy kilku instancjach na jednej domenie ustaw --cookie-suffix. Bez tego ciasteczka sesji się nadpisują i wylogowujesz się z jednej instancji, logując do drugiej.
HTTPS nie jest ozdobą
Webviews w VS Code stoją na service workerach, a te działają wyłącznie w bezpiecznym kontekście. Wejście na instancję po adresie IP bez certyfikatu daje w konsoli błąd rejestracji service workera i puste panele wszędzie tam, gdzie rozszerzenie rysuje własny widok — podgląd Markdown, interfejsy debuggerów, panele testów. Bezpieczny kontekst to localhost, 127.0.0.1 albo domena z prawdziwym certyfikatem.
Osobny przypadek: Safari nie obsługuje WebSocketów po TLS 1.3. Konfiguracja proxy wymuszająca wyłącznie 1.3 odcina użytkowników Safari, a w konsoli przeglądarki pojawia się OSSStatus: 9836. Trzeba dopuścić TLS 1.2.
Wbudowany proxy portów
Funkcja, dla której warto rozważyć code-server zamiast code serve-web, i jednocześnie ta, która generuje najwięcej pytań. Edytor umie proxować dowolny port maszyny, na której działa, za swoim uwierzytelnieniem. Aplikacja pod artisan serve, serwer Vite, panel Horizona, Mailpit — wszystko to jest dostępne bez otwierania kolejnych portów w firewallu.
/proxy kontra /absproxy
Ścieżka /proxy/<port>/ obcina swój prefiks przed przekazaniem żądania dalej. Aplikacja dostaje więc żądanie tak, jakby stała w katalogu głównym, i musi używać adresów relatywnych oraz ukośnika na końcu ścieżek. Wariant /absproxy/<port> przekazuje ścieżkę bez zmian, ale wymaga poinformowania aplikacji, pod jakim prefiksem jest serwowana.
Dokumentacja podaje gotowe przepisy dla create-react-app, Vue, Angulara i Svelte. Dla Vite'a, na którym siedzi dzisiejszy Laravel, ich nie ma i sprowadza się to do dwóch ustawień: base w vite.config.js musi odpowiadać prefiksowi proxy, a klient HMR musi wiedzieć, na jaki port i ścieżkę otworzyć WebSocket (server.hmr). Jeśli code-server sam jest serwowany z podścieżki, dochodzi do tego --abs-proxy-base-path.
Da się to ustawić, ale w naszej ocenie to walka nie o tę stawkę. Prostsze są dwa wyjścia: albo poddomeny (niżej), albo przekierowanie portu Vite przez SSH i zostawienie go pod localhost, gdzie żadna z tych zmiennych nie występuje.
Poddomeny zamiast podścieżek
Wariant, który producent sam zaleca i który omija całą klasę problemów z prefiksami. Wymaga wpisu DNS z wieloznacznikiem *.code.example.com i certyfikatu obejmującego te poddomeny:
code-server --proxy-domain code.example.comWtedy port 5173 jest pod 5173.code.example.com, a aplikacja widzi normalny adres w katalogu głównym. Mechanizm działa na nagłówku Host, więc odwrotne proxy musi go przekazywać.
Panel Ports w edytorze potrafi też generować odnośniki do zewnętrznego proxy — wystarczy ustawić VSCODE_PROXY_URI, na przykład https://{{port}}.code.example.com. Obsługiwane są też ścieżki relatywne (./proxy/{{port}}).
Dwie mniejsze rzeczy z tego obszaru: przy włączonym uwierzytelnieniu proxy uwierzytelnia także żądania preflight, które zwykle idą bez ciasteczek, więc CORS-owe wywołania trzeba przepuścić flagą --skip-auth-preflight. A jeśli proxy w ogóle nie chcesz, wyłącza je --disable-proxy (albo CS_DISABLE_PROXY=1) — wtedy warto jeszcze ustawić remote.autoForwardPorts na false, bo sam panel Ports zostaje widoczny i będzie proponował odnośniki, które nie działają.
Luka, która pokazuje, po co się aktualizować
W wydaniu 4.124.2 z 16 czerwca 2026 naprawiono zachowanie, które warto znać, bo dobrze ilustruje model zagrożeń tego narzędzia. Przy wbudowanym uwierzytelnianiu hasłem ciasteczko z tokenem sesji było przekazywane do proxowanego portu lokalnego. Usługa działająca na tym porcie — niekoniecznie Twoja, bo wystarczy dowolny proces innego użytkownika na tej samej maszynie — mogła tym ciasteczkiem zalogować się do edytora i wykonywać polecenia jako Ty. Poprawka wycina token z ciasteczka przed przekazaniem żądania dalej.
Wniosek praktyczny wynika z polityki bezpieczeństwa projektu: poprawki są publikowane w kolejnym wydaniu, bez backportów do starszych linii, a wspierana jest wyłącznie wersja najnowsza. Zespół zobowiązuje się naprawić zgłoszony problem w ciągu 90 dni. Instancja przypięta do wersji sprzed pół roku nie dostanie żadnej łatki — przy cotygodniowych wydaniach aktualizacja musi być procesem, nie jednorazową decyzją.
code-server obok Laravel Saila
Najprościej wstawić edytor jako kolejną usługę do compose.yaml, obok kontenerów projektu. Katalog projektu montujemy w tym samym miejscu, w którym widzi go aplikacja, a port wiążemy z pętlą lokalną:
code-server:
image: 'codercom/code-server:4.133.0'
container_name: 'code-server'
user: '${WWWUSER}:${WWWGROUP}'
environment:
HASHED_PASSWORD: '${CODE_SERVER_HASHED_PASSWORD}'
DOCKER_USER: 'sail'
command:
- '--disable-telemetry'
- '--disable-getting-started-override'
- '/var/www/html'
volumes:
- '.:/var/www/html'
- 'code-server-data:/home/coder/.local/share/code-server'
- '/var/run/docker.sock:/var/run/docker.sock'
ports:
- '127.0.0.1:${CODE_SERVER_PORT:-8080}:8080'
networks:
- sailOsobny wolumen na /home/coder/.local/share/code-server jest tu konieczny — bez niego przy każdym down tracisz rozszerzenia, ustawienia i historię. Montowanie /var/www/html zamiast /home/coder/project daje w terminalu edytora te same ścieżki, jakie widzi aplikacja, więc ślady stosu z logów Laravela klikają się poprawnie.
Gniazdo Dockera jest w tym przykładzie po to, żeby z terminala edytora dało się odpalać vendor/bin/sail artisan — obraz code-servera nie ma PHP, więc polecenia i tak wykonuje kontener aplikacji. Wymaga to doinstalowania klienta Dockera w kontenerze edytora. I wymaga świadomości ceny:
Zamontowane/var/run/docker.sockjest równoważne uprawnieniom roota na maszynie hosta. Kto ma dostęp do tego edytora, ma faktycznie hosta. Na maszynie deweloperskiej to akceptowalne, na wspólnym serwerze — nie; tam wybierz drugie wyjście, czylidocker execz hosta albo osobny kontener z PHP-em i zamontowanym tym samym wolumenem kodu.
Dalsze uwagi z naszego wdrożenia: baza jest widoczna pod nazwą usługi (pgsql:5432), bo edytor stoi w tej samej sieci Compose'a, więc rozszerzenia bazodanowe konfiguruje się jak z wnętrza aplikacji, a nie jak z hosta. Xdebug działa bez zmian, bo debugger nasłuchuje w kontenerze aplikacji i nie interesuje go, gdzie jest interfejs edytora. Vite z HMR-em przez proxy podścieżkowy wymaga opisanych wyżej zabiegów — przy pracy lokalnej po prostu przekieruj port 5173 tunelem.
I rzecz oczywista, o której łatwo zapomnieć przy dopisywaniu usługi do pliku, który jest w repozytorium: kontener z edytorem widzi cały kod projektu, plik .env i sieć bazy danych. Hasło do niego jest hasłem do tego wszystkiego.
Rozszerzenia: Open VSX zamiast marketplace’u Microsoftu
Najważniejsze ograniczenie code-servera nie jest techniczne, tylko licencyjne. Rdzeń VS Code jest otwarty, ale marketplace i część rozszerzeń Microsoftu — nie, a regulamin marketplace’u dopuszcza korzystanie z niego wyłącznie razem z produktami i usługami Visual Studio. code-server nie jest produktem Microsoftu, więc do tego katalogu nie sięga.
Zamiast niego działa Open VSX — otwarty rejestr prowadzony przez Eclipse Foundation, z którego korzystają też inne forki, w tym VSCodium i Gitpod. Technicznie da się podstawić dowolny katalog przez zmienną EXTENSIONS_GALLERY (odpowiada polu extensionsGallery w product.json VS Code), w tym katalog Microsoftu. Producent to odradza wprost i my też: byłoby to korzystanie z usługi wbrew jej regulaminowi, w narzędziu używanym komercyjnie u klienta.
Co z naszego stacku jest dostępne
Sprawdziliśmy Open VSX pod kątem tego, czego realnie używamy przy Laravelu (stan na 19 sierpnia 2026):
- PHP Intelephense — 1.18.5, aktualizacja z 21 czerwca 2026, ponad 2,1 mln pobrań,
- PHP Debug (Xdebug) — 1.40.1 z 7 kwietnia 2026, MIT,
- Laravel (oficjalne rozszerzenie zespołu Laravela) — 2.0.0 z 6 sierpnia 2026,
- Tailwind CSS IntelliSense — 0.16.0 z 20 lipca 2026,
- ESLint 3.0.34, Prettier 12.4.0, GitLens w wydaniu z 18 sierpnia 2026, Docker, Python,
- Claude Code — 2.1.235 z 18 sierpnia 2026, czyli agentowe narzędzie AI działa w code-serverze bez obchodzenia czegokolwiek.
Dla zespołu pracującego na PHP, Laravelu, Tailwindzie i Vue albo Reakcie ten zestaw jest kompletny. Rok czy dwa lata temu to zdanie nie byłoby prawdziwe i to jest realna zmiana: Open VSX przestał być katalogiem z brakami w podstawach.
Czego nie będzie
Zamknięte rozszerzenia Microsoftu i GitHuba nie są dostępne i nie da się tego obejść legalnie:
- GitHub Copilot — brak w Open VSX. To najczęstszy powód, dla którego zespół po tygodniu wraca do desktopowego VS Code.
- Live Share — wspólna edycja w czasie rzeczywistym. Zamiennikami są rozszerzenia zewnętrzne (Duckly, CodeTogether), z których część wymaga uruchomienia code-servera z
--enable-proposed-api. - Remote Development (SSH, Containers, WSL) — czyli akurat te rozszerzenia, które robią to samo od strony desktopu.
Osobna sprawa to skróty klawiszowe. Część z nich przechwytuje przeglądarka, zanim dotrą do edytora — Ctrl+W, Ctrl+N, Ctrl+T i pochodne. Rozwiązanie z dokumentacji to zainstalowanie instancji jako aplikacji PWA (w Chrome ikoną w pasku adresu, w Firefoksie przez dodatek). Wtedy okno nie ma paska kart i skróty trafiają tam, gdzie powinny. Bez PWA trzeba przemapować część klawiszy i to jest pierwsza rzecz, na którą narzeka każdy, kto siada do code-servera na dłużej niż kwadrans.
Instalacja rozszerzeń z linii poleceń
Przy zarządzaniu wieloma instancjami wygodniej wgrywać rozszerzenia skryptem niż klikać w panelu:
code-server --install-extension bmewburn.vscode-intelephense-client
code-server --install-extension xdebug.php-debug
code-server --install-extension laravel.vscode-laravel
code-server --install-extension bradlc.vscode-tailwindcssRozszerzenie spoza katalogu wgrywa się z pliku .vsix — tą samą flagą ze ścieżką do pliku albo poleceniem Extensions: Install from VSIX w palecie. Rozszerzenia lądują w ~/.local/share/code-server/extensions, ustawienia i skróty w ~/.local/share/code-server, a logi w ~/.local/share/code-server/coder-logs. Konfigurację z desktopowego VS Code można przenieść, kopiując ~/.vscode albo wskazując --user-data-dir.
Telemetrię wyłącza --disable-telemetry. Promocję Codera w ekranie powitalnym — --disable-getting-started-override.
Drobne rzeczy, które robią różnicę
Kilka funkcji, które nie trafiają do opisów, a przydają się w utrzymaniu:
- Odnośnik do pliku i linii. Parametr
payloadw adresie otwiera konkretny plik w konkretnym miejscu, a zgotoLineModetakże w konkretnej linii i kolumnie. Adres wygląda tak:?folder=/var/www/html&payload=[["gotoLineMode","true"],["openFile","vscode-remote://code.example.com/var/www/html/app/Models/Post.php:42:5"]](z zakodowaną wartościąpayload). To ten sam mechanizm, którego używa vscode.dev, więc nie wymaga żadnej konfiguracji. Dobrze się nadaje do generowania odnośników z narzędzi wewnętrznych — ze zgłoszenia w trackerze albo z logu błędów prosto w linijkę kodu. /healthz— endpoint bez uwierzytelnienia, zwracający status i znacznik ostatniego pulsu, do wpięcia w monitoring. Odpytanie go nie liczy się jako aktywność użytkownika.- Plik pulsu i usypianie. Dopóki ktoś ma otwartą kartę, edytor odświeża
~/.local/share/code-server/heartbeatraz na minutę. Na tym można oprzeć wyłączanie maszyny — albo od razu użyć--idle-timeout-seconds, żeby instancja gasiła się sama. Przy maszynach w chmurze rozliczanych za godziny to bezpośrednia oszczędność. - Czas na powrót po rozłączeniu —
--reconnection-grace-time, domyślnie 10800 sekund, czyli trzy godziny. Po tym czasie kartę trzeba przeładować. Przy dostępie z telefonu w metrze warto o tym wiedzieć, zanim zacznie się szukać winy w proxy. - Własne napisy i nazwa aplikacji —
--i18nz plikiem JSON podmienia teksty ekranu logowania i powitania,--app-name(alboCODE_SERVER_APP_NAME) zmienia nazwę widoczną w tytule okna. Przy instancji stawianej dla klienta to pięć minut pracy, a wygląda inaczej niż domyślny ekran nieznanego narzędzia. - Blokada pobierania plików —
--disable-file-downloads. Nie jest to zabezpieczenie (terminal nadal jest terminalem), ale w środowisku z wymogami compliance zdejmuje najprostszą drogę wyniesienia kodu. - Diagnostyka —
--log debugalbo--log trace(aliasy--verbose,-vvv). Przy zgłoszeniu błędu i tak trzeba dołożyć konsolę i zakładkę sieciową przeglądarki, bo połowa problemów jest po stronie klienta.
Na co uważać
- Brak Copilota i Live Share. Ograniczenie licencyjne, nie do obejścia. Sprawdź, czym pracuje zespół, przed wdrożeniem.
- Jedno hasło, jedna osoba. Nie ma kont ani ról. Wielu użytkowników robi się jedną instancją na osobę — producent zaleca do tego maszyny wirtualne, a na Kubernetesie kubevirt albo sysbox, żeby każdy dostał środowisko przypominające VM-kę, nie sam kontener.
- Wspierana jest tylko najnowsza wersja. Brak backportów poprawek bezpieczeństwa. Aktualizacje trzeba wpisać w harmonogram.
- Skróty klawiszowe przechwytywane przez przeglądarkę. Bez PWA praca jest męcząca.
- Webviews wymagają bezpiecznego kontekstu. Instancja pod adresem IP bez certyfikatu będzie mieć puste panele podglądu.
- Safari i TLS 1.3. WebSockety nie działają; trzeba dopuścić 1.2.
- Brak wydań dla Windows.
- Chart Helma poza repozytorium chartów i utrzymywany przez społeczność, z nieodświeżoną dokumentacją.
- macOS wymaga nadania Node dostępu do dysku, żeby edytor widział katalogi Dokumenty, Pobrane i Pulpit.
- To nie zamiennik PhpStorma. Jeśli zespół żyje refaktoringami i inspekcjami IDE JetBrains, code-server ich nie zastąpi — jest VS Code, z możliwościami VS Code.
Podsumowanie
code-server jest najsensowniejszym sposobem postawienia VS Code w przeglądarce na własnej infrastrukturze i jednym z niewielu narzędzi w tej kategorii, o których po siedmiu latach można powiedzieć, że po prostu działają i są utrzymywane w rytmie tygodnia.
Co daje:
- pełny workbench VS Code z terminalem, gitem i debuggerem, dostępny z przeglądarki — także z urządzenia bez klienta SSH,
- wydania nadążające za upstreamem: 4.133.0 z 17 sierpnia 2026 odpowiada Code 1.133.0, przy kadencji jednego wydania na tydzień,
- instalację w każdym praktycznym wariancie: skrypt,
.deb,.rpm, AUR, Homebrew, archiwum standalone, npm, obraz Dockera dla amd64 i arm64, chart Helma, - konfigurację w jednym pliku YAML, w którym każdy klucz odpowiada fladze CLI, z hasłem trzymanym jako hash argona,
- wbudowany proxy do portów maszyny za uwierzytelnieniem edytora, w wariancie podścieżkowym i poddomenowym, wpięty w panel Ports,
- rzeczy potrzebne w utrzymaniu:
/healthz, plik pulsu, automatyczne usypianie bezczynnej instancji, własne napisy i nazwa aplikacji, blokada pobierania plików, - komplet rozszerzeń dla stacku laravelowego w Open VSX — Intelephense, PHP Debug, oficjalne rozszerzenie Laravela, Tailwind, ESLint, Prettier, GitLens, a także Claude Code,
- projekt w dobrej kondycji: 78,9 tysiąca gwiazdek, sponsor instytucjonalny, jasna polityka bezpieczeństwa i publiczny changelog.
Licencja: MIT, czyli przy komercyjnym użyciu nie ma o czym rozmawiać — można stawiać instancje u klientów, modyfikować kod i nie powstają z tego żadne obowiązki poza zachowaniem noty licencyjnej. Prawnie istotne jest natomiast coś innego niż licencja samego kodu: regulamin marketplace’u Microsoftu, który zastrzega korzystanie z katalogu rozszerzeń dla produktów i usług Visual Studio. Podstawienie tego katalogu w code-serverze jest technicznie możliwe i właśnie dlatego trzeba to zapisać wprost — u klienta tego nie robimy. Rozszerzenia bierzemy z Open VSX albo z plików .vsix od ich autorów, a brak Copilota i Live Share traktujemy jako warunek początkowy, nie problem do obejścia.