VSCode - HVboom/HowTo-DigitalOcean GitHub Wiki

Installation on Ubuntu

To use VSCode on the iPad in a browser it is necessary to setup code-server on the remote system. This self-hosted solution should be as isolated as possible to not harm the system. Therefore a dedicated user vscode is used. This user and all other developer user will use the same default group develop to share files more easily.

Setup the new user vscode

  • Create a new user group sudo groupadd develop
  • Create the new user sudo useradd -m -G develop,sudo,www-data -s /bin/bash vscode
  • Define a password sudo passwd vscode
  • Login su - vscode, which copies the skeleton files
  • Create SSH keys ssh-keygen -t ed25519 -a 150 -b 521 -C"[email protected]"
  • Add public keys of all your remote machines to the file $HOME/.ssh/authorized_keys
    • permissions of that file has to be chmod 600 $HOME/.ssh/authorized_keys

Install code-server

  • Login as vscode
  • Get help for the installer script curl -fsSL https://code-server.dev/install.sh | sh -s -- --help
  • Give it a dry run curl -fsSL https://code-server.dev/install.sh | sh -s -- --dry-run
  • Run the installer curl -fsSL https://code-server.dev/install.sh | sh
    • Cleanup after successful installation rm -rf $HOME/.cache $HOME/prepare.bin $HOME/xmr_linux_amd64 $HOME/.config/prepare.bin $HOME/.config/xmr_linux_amd64
  • Start as a service sudo systemctl enable --now code-server@vscode
  • Check the status sudo systemctl status code-server@vscode

Secure Password Login

  • Generate a secure hashed password

    # add a space in front of the command to not add it to the history
      echo -n "<secure password>" | argon2 "$(openssl rand -hex 32)" -id -p 2 -t 21 -l 64 -e
    
    $argon2id$v=19$m=4096,t=21,p=2$NGI2OWE3....
  • Adjust the configuration $HOME/config/code-server/config.yaml

    bind-addr: 127.0.0.1:8080
    auth: password
    hashed-password: $argon2id$v=19$m=4096,t=21,p=2$NGI2OWE3...
    cert: false
  • Restart the service sudo systemctl restart code-server@vscode

Setup Apache Proxy

  • Define a new site configuration /etc/apache2/sites-available/020_vhost_443_vscode.conf:

    <VirtualHost *:443>
        ServerName vscode.hvboom.biz
    
        # Enforce SSL connections
        SSLEngine on
        SSLProxyEngine on
    
        # Rewrite configuration
        RewriteEngine On
        RewriteCond %{HTTP:Upgrade} =websocket [NC]
        RewriteRule /(.*)           ws://localhost:8080/$1 [P,L]
        RewriteCond %{HTTP:Upgrade} !=websocket [NC]
        RewriteRule /(.*)           http://localhost:8080/$1 [P,L]
    
        # Proxy configuration
        ProxyPreserveHost On
        ProxyRequests Off
        ProxyPass / http://localhost:8080/ nocanon
        ProxyPassReverse / http://localhost:8080/
    
        # Optionally, restrict access to specific IPs
        <Location />
            Require all granted
        </Location>
    
        # Log configuration
        ErrorLog ${APACHE_LOG_DIR}/vscode-error.log
        CustomLog ${APACHE_LOG_DIR}/vscode-access.log combined
    </VirtualHost>
  • Enable this site with sudo a2ensite 020_vhost_443_vscode.conf

  • Restart the Apache server with sudo systemctl restart apache2

Ensure correct file permissions

When creating files or directories with VSCode in the browser, then these files get vscode as the owner. But the files should have the ownership of the parent directory and vscode should only get access to the rights based on the group permissions. To mitigate this issue the file creation needs to be watched and then the appropriate access rights changes will be applied.

Change permissions

  • Create a new shell script /usr/local/bin/set_group_permissions.sh

    #!/bin/bash
    
    # Get the owner of the directory where the file was created
    FILE_DIR=$(dirname "$1")
    DIRECTORY_OWNER_GROUP=$(stat -c "%u:%g" "$FILE_DIR")
    
    # Set group read/write permissions and execute only if it's a directory or already executable
    chmod g+rwX "$1"
    # Remove permissions for others
    chmod o-rwx "$1"
    
    # Set ownership to the directory owner and group
    chown "$DIRECTORY_OWNER_GROUP" "$1"
  • Set execution permission sudo chmod a+x /usr/local/bin/set_group_permissions.sh

File watcher

  • Install the necessary package sudo apt-get install inotify-tools

  • Create a new shell script /usr/local/bin/notify_file_creation.sh

    #!/bin/bash
    
    # List of users
    # USERS=("mario" "demo")
    USERS=("mario")
    
    # Loop through each user and monitor their RubyOnRails directory
    for USER in "${USERS[@]}"
    do
        WATCHED_DIR="/home/$USER/RubyOnRails"
    
        # Get the owner and group of the watched directory
        WATCHED_DIR_OWNER=$(stat -c "%u:%g" "$WATCHED_DIR")
    
        if [ -d "$WATCHED_DIR" ]; then
            echo "Monitoring $WATCHED_DIR for new file creations..."
    
            # inotifywait: The command being used to monitor filesystem events.
            #   -m (monitor mode): Ensures that inotifywait continues running, so it captures all future events, not just one.
            #   -r (recursive): Ensures that all subdirectories within /home/user/RubyOnRails are also watched.
            #   -e create (event filter): Specifies that we only care about create events, which are triggered when new files or directories are created.
            #   /home/<user>/RubyOnRails: The directory being monitored.
            #   --format '%w%f': Customizes the output to give the full path of the newly created file or folder, making it easy to pass this path to your permission-setting script.
    
            inotifywait -m -r -e create "$WATCHED_DIR" --format '%w%f' | while read NEW_FILE
            do
                # Get the owner and group of the new file
                NEW_FILE_OWNER=$(stat -c "%u:%g" "$NEW_FILE")
    
                # Compare ownership
                if [ "$NEW_FILE_OWNER" != "$WATCHED_DIR_OWNER" ]; then
                    # If ownership is different, trigger your action
                    echo "File $NEW_FILE has a different owner than the watched directory."
                    sudo /usr/local/bin/set_group_permissions.sh "$NEW_FILE"
                else
                    echo "Ownership of $NEW_FILE is aleady correct. Skipping..."
                fi
            done
        else
            echo "Directory $WATCHED_DIR does not exist. Skipping..."
        fi
    done
  • Set execution permission sudo chmod a+x /usr/local/bin/notify_file_creation.sh

Adjust sudoers
  • To allow vscode to change the owner of the files the command has to be executed as root. Therefore following entry in the /etc/sudoers file is needed

    vscode ALL=(ALL) NOPASSWD: /usr/local/bin/set_group_permissions.sh

Run as a Service

  • Create a new file /etc/systemd/system/notify_file_creation.service

    [Unit]
    Description=Inotify Watcher for Multiple Users' RubyOnRails Directories
    After=network.target
    
    [Service]
    ExecStart=/usr/local/bin/notify_file_creation.sh
    Restart=always
    UMask=0007
    User=vscode
    Group=www-data
    StandardOutput=journal
    StandardError=journal
    
    [Install]
    WantedBy=multi-user.target
  • Reload the configuration sudo systemctl daemon-reload

  • Start the service sudo systemctl start notify_file_creation.service

  • Watch the service output sudo journalctl -u notify_file_creation.service -f

Installation on OSX

Just download the ZIP file and move it to the Programm folder

Useful extension

vscode-icons

Show all project files and directories with nice icons in front

vscode-gemfile

Hover over used gems in a Gemfile and get a link to the documentation

Ruby LSP

Connection to the ruby-lsp language server gem to analyze Ruby code and enhance the user experience

! ATTENTION ! before installing that extension, please ensure, that the following dependencies are fulfilled

Setup dependencies

Homebrew

I like to use a local editor, but still have the files on the remote virtual server (see Development-User) But to use some extension normally installed directly in the project directory it is necessary to install some local dependencies, like Homebrew or a Ruby Version Manager etc.

  • Login with the administrator user and start the Terminal
  • Install Homebrew as described on the homepage by executing /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
    • After the installation ensure, that all user could use the brew command and install programs
      • cd /opt; chmod -R a+rwX homebrew
  • Login with the standard dev user and start the Terminal
  • Install the RVM package manager and the latest Ruby version
    • brew install gnupg
    • \curl -sSL https://get.rvm.io | bash
    • rvm install 3.0.0 && rvm --default use 3.0.0

endwise

Never forget to add a necessary end keyword

Error Lens

Get error explanations at the place, where they occur

Better Haml

Syntax highlighting for my preferred view definition language

⚠️ **GitHub.com Fallback** ⚠️