Files
docudjeex/content/en/3.serveex/8.development/1.code-server.md
T

9.2 KiB
Raw Blame History

title, description
title description
Code-Server Install code-server to run VS Code in your browser from your homelab, mount folders and expose it securely with SWAG.

:ellipsis{left=0px width=40rem top=10rem blur=140px zIndex=60}

Code-Server

::note 🎯 Goals:

  • Install code-server
  • Mount folders into VS Code
  • Expose code-server with Swag ::

code-server is a container that lets you access VS Code via a web UI in a Linux environment. It's literally VS Code and your projects in your pocket, available anywhere.

code-server

Installation

::note

For this setup, well use the image maintained by LinuxServer.io. ::

::file-tree

tree: /: - docker: - code-server: - compose.yaml - .env - config/ - (any folder you want to mount in VS Code)/

::

Open Dockge, click on compose, name the stack code-server, and paste the following:

---
services:
  code-server:
    image: lscr.io/linuxserver/code-server:latest
    container_name: code-server
    environment:
      - PUID=${PUID}
      - PGID=${GUID}
      - TZ=Etc/UTC
      - HASHED_PASSWORD=${PW}
    volumes:
      - /docker/code-server/config:/config
    # add folders to mount in VS Code
    # - /path/to/folder:/folder
    ports:
      - 8443:8443
    restart: unless-stopped

::tip{icon=""} Add the Watchtower label to each container to automate updates

```yaml [compose.yaml]
services:
  code-server:
    #...
    labels:

      - com.centurylinklabs.watchtower.enable=true
```

::

Choose a password and generate its hash:

echo -n "yourpassword" | npx argon2-cli -e

Save the result carefully. Find your PUID and GUID with:

id yourusername

Fill in the .env file with the values you found, for example:

PW='$argon2i$v=19$m=4096,t=3,p=1$wST5QhBgk2lu1ih4DMuxvg$LS1alrVdIWtvZHwnzCM1DUGg+5DTO3Dt1d5v9XtLws4'
PUID=1000
GUID=1000

::warning

Note: Make sure to wrap the hash in single quotes ' ::

Deploy the container and go to http://yourserverip:8443. Voilà, your code-server instance is up and running in the browser!

::caution

If it fails: check your firewall rules. ::

Mount Folders

You can mount folders into VS Code by adding the relevant volumes in compose.yaml (or via Dockge), then redeploy the container.

---
services:
  code-server:
    #...
    volumes:
      - /path/to/folder:/folder

Once inside VS Code, you'll have access to the mounted folder.

Expose code-server with Swag

The whole point of such a solution is to access it remotely from any device. To do this, well expose code-server via Swag.

::note

Preliminary: We assume youve created a subdomain like code.yourdomain.com with a CNAME pointing to yourdomain.com in your DNS zone. Unless you're using Cloudflare Zero Trust, we also assume youve forwarded port 443 from your router to port 443 on your server using NAT rules. ::

In Dockge, go to the SWAG stack and edit the compose file to add code-servers network:

---
services:
  swag:
     container_name: # ...
      # ... 
     networks:           # Connects the container to a custom network 
      # ...           
      - code-server      # Name of the network defined in the stack
    
networks:                # Defines the custom network
  # ...
  code-server:           # Name of the network defined in the stack
    name: code-serveur   # Actual name of the external network
    external: true       # Indicates its an external network

::note

We assume the network name is code-server_default. You can verify that the connection works by visiting the SWAG dashboard at http://yourserverip:81. ::

Redeploy the stack by clicking “deploy” and wait until SWAG is fully operational.

Inside the Swag config folders, create the file code.subdomain.conf.

::tip{icon=""} Tip: You can use File Browser Quantum to navigate and edit your files instead of using terminal commands. ::

sudo nano /docker/swag/config/nginx/proxy-confs/code.subdomain.conf

Paste the following configuration:

## Version 2023/12/19

server {
    listen 443 ssl;
    listen [::]:443 ssl;

    server_name code.*;

    include /config/nginx/ssl.conf;

    client_max_body_size 0;

    #if ($lan-ip = yes) { set $geo-whitelist yes; }
    #if ($geo-whitelist = no) { return 404; }
    if ($geo-blacklist = no) { return 404; }

    # enable for ldap auth (requires ldap-location.conf in the location block)
    #include /config/nginx/ldap-server.conf;

    # enable for Authelia (requires authelia-location.conf in the location block)
    #include /config/nginx/authelia-server.conf;

    # enable for Authentik (requires authentik-location.conf in the location block)
    #include /config/nginx/authentik-server.conf;

    location / {
        # enable the next two lines for http auth
        #auth_basic "Restricted";
        #auth_basic_user_file /config/nginx/.htpasswd;

        # enable for ldap auth (requires ldap-server.conf in the server block)
        #include /config/nginx/ldap-location.conf;

        # enable for Authelia (requires authelia-server.conf in the server block)
        #include /config/nginx/authelia-location.conf;

        # enable for Authentik (requires authentik-server.conf in the server block)
        #include /config/nginx/authentik-location.conf;

        include /config/nginx/proxy.conf;
        include /config/nginx/resolver.conf;
        set $upstream_app code-server;
        set $upstream_port 8443;
        set $upstream_proto http;
        proxy_pass $upstream_proto://$upstream_app:$upstream_port;
    }
}

Press :kbd{value="Ctrl+O"}, then :kbd{value="Enter"} to save, and :kbd{value="Ctrl+X"} to exit.

Thats it! code-server is now exposed!

Protecting code-server with TinyAuth

Add TinyAuth's forward-auth check directly to code.subdomain.conf, the same way as the TinyAuth guide:

## Version 2023/12/19

server {
    listen 443 ssl;
    listen [::]:443 ssl;

    server_name code.*;

    include /config/nginx/ssl.conf;

    client_max_body_size 0;

    #if ($lan-ip = yes) { set $geo-whitelist yes; }
    #if ($geo-whitelist = no) { return 404; }
    if ($geo-blacklist = no) { return 404; }

    # enable for ldap auth (requires ldap-location.conf in the location block)
    #include /config/nginx/ldap-server.conf;

    # enable for Authelia (requires authelia-location.conf in the location block)
    #include /config/nginx/authelia-server.conf;

    # enable for Authentik (requires authentik-location.conf in the location block)
    #include /config/nginx/authentik-server.conf;

    location /tinyauth {
        internal;
        proxy_pass http://tinyauth:3000/api/auth/nginx;
        proxy_pass_request_body off;
        proxy_set_header Content-Length "";
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-Host $http_host;
        proxy_set_header X-Forwarded-Uri $request_uri;
    }

    location @tinyauth_login {
        return 302 https://tinyauth.mydomain.com/login?redirect_uri=$scheme://$http_host$request_uri;
    }

    location / {
        auth_request /tinyauth;
        error_page 401 = @tinyauth_login;

        # enable the next two lines for http auth
        #auth_basic "Restricted";
        #auth_basic_user_file /config/nginx/.htpasswd;

        # enable for ldap auth (requires ldap-server.conf in the server block)
        #include /config/nginx/ldap-location.conf;

        # enable for Authelia (requires authelia-server.conf in the server block)
        #include /config/nginx/authelia-location.conf;

        # enable for Authentik (requires authentik-server.conf in the server block)
        #include /config/nginx/authentik-location.conf;

        include /config/nginx/proxy.conf;
        include /config/nginx/resolver.conf;
        set $upstream_app code-server;
        set $upstream_port 8443;
        set $upstream_proto http;
        proxy_pass $upstream_proto://$upstream_app:$upstream_port;
    }
}

::note

The location /tinyauth block runs inside SWAG's own container, so SWAG needs to be on TinyAuth's Docker network to reach it by name (tinyauth here). This should already be set up from exposing TinyAuth itself. If you run into an error, double-check SWAG's compose file still has that network attached. ::

::tip{icon=""} Tip: You can protect this app with Authentik instead of TinyAuth by opening code.subdomain.conf and uncommenting the lines include /config/nginx/authentik-server.conf; and include /config/nginx/authentik-location.conf;. Dont forget to create an application and provider in Authentik. ::