Add initial setup scripts and configuration files for development environment

This commit is contained in:
2025-03-03 00:24:07 +01:00
parent 92d53d9c1c
commit f33b76ac38
15 changed files with 1365 additions and 0 deletions
+3
View File
@@ -0,0 +1,3 @@
venv
app/frontend/node_modules
app/venv
+35
View File
@@ -0,0 +1,35 @@
# Usa Debian como base
FROM debian:bookworm-slim
# Definir el directorio de trabajo
WORKDIR /app
# Instalar dependencias necesarias
RUN apt-get update && \
apt-get install -y --no-install-recommends \
bash \
curl \
gnupg \
apt-transport-https \
ca-certificates && \
rm -rf /var/lib/apt/lists/*
# Descargar e instalar code-server
RUN curl -sSL https://code-server.dev/install.sh | sh || echo "Error al instalar code-server" && \
which code-server || echo "code-server no encontrado" && \
code-server --version || echo "Error al obtener la versión de code-server"
# Exponer el puerto por defecto de code-server
EXPOSE 8080
# Definir el usuario y grupo de trabajo
USER root
# Comando para iniciar code-server como root
ENTRYPOINT ["/bin/bash", "-c", "code-server /app --bind-addr 0.0.0.0:8080 --auth none -vvv"]
+3
View File
@@ -0,0 +1,3 @@
#!/bin/bash
# Obtener el ID del contenedor actual
cat /proc/self/cgroup | grep ":cpu:" | sed 's/.*\///' | head -n 1 | cut -c1-12
+29
View File
@@ -0,0 +1,29 @@
#!/bin/bash
# Lista de extensiones a instalar
EXTENSIONES=(
"ms-python.python"
"ms-python.vscode-pylance"
"ms-toolsai.jupyter"
"ms-toolsai.jupyter-keymap"
"ms-toolsai.jupyter-renderers"
"ms-toolsai.vscode-jupyter-cell-tags"
"ms-toolsai.vscode-jupyter-slideshow"
)
# Función para instalar extensiones
instalar_extensiones() {
for EXT in "${EXTENSIONES[@]}"; do
echo "Instalando $EXT..."
code --install-extension "$EXT"
if [ $? -eq 0 ]; then
echo "$EXT instalado correctamente."
else
echo "❌ Error al instalar $EXT."
fi
done
}
# Ejecutar la instalación
instalar_extensiones
echo "🚀 ¡Instalación completada!"
+49
View File
@@ -0,0 +1,49 @@
#!/bin/bash
# Actualizar repositorios
echo "Actualizando repositorios..."
apt-get update
# Instalar compiladores y herramientas necesarias
echo "Instalando gcc, make y otras dependencias..."
apt-get install -y gcc make build-essential linux-headers-$(uname -r) python3-dev
# Instalar Python 3, pip y virtualenv
echo "Instalando Python 3, pip y virtualenv..."
apt-get install -y python3 python3-pip python3-venv
# Crear alias para 'python' si no existe
if ! command -v python &> /dev/null; then
echo "Creando alias para 'python'..."
ln -s /usr/bin/python3 /usr/bin/python
fi
# Actualizar pip a la última versión globalmente
echo "Actualizando pip globalmente..."
python3 -m pip install --upgrade pip
# Instalar wheel para facilitar la instalación de paquetes compilados
echo "Instalando wheel globalmente..."
python3 -m pip install wheel
# Instalar Jupyter y psutil globalmente
echo "Instalando Jupyter Notebook y psutil globalmente..."
python3 -m pip install jupyter psutil
# Crear un perfil de configuración por defecto para Jupyter
echo "Creando configuración por defecto para Jupyter..."
jupyter notebook --generate-config
# Añadir configuración para ejecutar Jupyter sin token en localhost
CONFIG_FILE=$(jupyter --config-dir)/jupyter_notebook_config.py
echo "c.NotebookApp.ip = '0.0.0.0'" >> $CONFIG_FILE
echo "c.NotebookApp.open_browser = False" >> $CONFIG_FILE
echo "c.NotebookApp.token = ''" >> $CONFIG_FILE
echo "Configuración creada en $CONFIG_FILE"
# Verificar la instalación
echo "Verificando la instalación..."
jupyter --version
echo "Instalación completada exitosamente."
echo "Para iniciar Jupyter, ejecuta: jupyter notebook --allow-root"
+81
View File
@@ -0,0 +1,81 @@
#!/bin/bash
set -eu
# 🛠 Actualizar repositorios
echo "Actualizando repositorios..."
apt-get update
# 🛠 Instalar Node.js, NPM, y dependencias necesarias si no están instalados
echo "Instalando Node.js, NPM y dependencias necesarias..."
apt-get install -y curl python3 make g++ git libc-dev bash
# 🛠 Instalar n (gestor de versiones de Node.js) globalmente
echo "Instalando el gestor de versiones 'n' para Node.js..."
curl -L https://raw.githubusercontent.com/tj/n/master/bin/n -o /usr/local/bin/n
chmod +x /usr/local/bin/n
# 🛠 Eliminar versiones conflictivas de Node.js y NPM
echo "Eliminando binarios conflictivos..."
rm -f /usr/local/bin/node || true
rm -f /usr/local/bin/npm || true
rm -f /usr/local/bin/npx || true
# 🛠 Crear directorio para versiones globales de Node.js si no existe
mkdir -p /usr/local/n
chown -R $(whoami) /usr/local/n
export N_PREFIX=/usr/local/n
# 🛠 Agregar N_PREFIX al PATH si no está
if ! grep -q "/usr/local/n/bin" <<< "$PATH"; then
export PATH="/usr/local/n/bin:$PATH"
echo 'export PATH="/usr/local/n/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc
fi
# 🛠 Función para configurar la versión de Node.js
setup_node_version() {
local VERSION=$1
echo "Instalando Node.js v$VERSION..."
n $VERSION
# 🛠 Crear enlaces simbólicos globales
ln -sf /usr/local/n/bin/node /usr/local/bin/node
ln -sf /usr/local/n/bin/npm /usr/local/bin/npm
ln -sf /usr/local/n/bin/npx /usr/local/bin/npx
# 🛠 Actualizar el PATH y limpiar caché de comandos
export PATH="/usr/local/n/bin:$PATH"
hash -r
# 🛠 Mostrar la versión instalada
echo "Node.js actualizado a:"
node -v
npm -v
}
# 🛠 Preguntar al usuario qué versión quiere instalar
echo "¿Qué versión de Node.js deseas instalar? (Ejemplo: 20)"
read -r NODE_VERSION
# 🛠 Ejecutar la instalación de la versión solicitada
setup_node_version $NODE_VERSION
# 🛠 Instrucciones para cambiar de versión rápidamente
cat << EOF
¡Node.js v$NODE_VERSION instalado correctamente! 🎉
Para cambiar de versión en el futuro, usa:
n <versión> # Ejemplo: n 18
Para listar versiones disponibles:
n ls-remote
Para listar versiones instaladas localmente:
n ls
Para borrar una versión específica:
n rm <versión> # Ejemplo: n rm 18
¡Disfruta usando Node.js con n! 🚀
EOF
+69
View File
@@ -0,0 +1,69 @@
#!/bin/bash
# Preguntar la versión de Python que se desea instalar
read -p "Ingresa la versión de Python que deseas establecer como global (por ejemplo, 3.11.2 o 3.8.9): " PYTHON_VERSION
# Validar el formato de la versión ingresada (más permisivo)
if [[ ! $PYTHON_VERSION =~ ^[0-9]+\.[0-9]+(\.[0-9]+)?([a-zA-Z0-9]+)?$ ]]; then
echo "❌ Formato inválido. Asegúrate de ingresar una versión válida (por ejemplo, 3.11.2, 3.8.9, 3.8.9b1)."
exit 1
fi
# Comprobar si pyenv está instalado
if ! command -v pyenv &> /dev/null; then
echo "pyenv no está instalado. Procediendo a instalarlo..."
# Instalar dependencias para pyenv
apt-get update
apt-get install -y curl git build-essential libssl-dev zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev libffi-dev liblzma-dev
# Instalar pyenv
curl https://pyenv.run | bash
# Configurar pyenv en el shell actual
export PATH="$HOME/.pyenv/bin:$PATH"
eval "$(pyenv init --path)"
eval "$(pyenv init -)"
eval "$(pyenv virtualenv-init -)"
# Agregar pyenv al bashrc para futuros shells
echo 'export PATH="$HOME/.pyenv/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(pyenv init --path)"' >> ~/.bashrc
echo 'eval "$(pyenv init -)"' >> ~/.bashrc
echo 'eval "$(pyenv virtualenv-init -)"' >> ~/.bashrc
fi
# Verificar si la versión de Python ya está instalada con pyenv
if pyenv versions --bare | grep -q "^$PYTHON_VERSION$"; then
echo "✅ Python $PYTHON_VERSION ya está instalado."
else
# Instalar la versión solicitada de Python
echo "Instalando Python $PYTHON_VERSION con pyenv..."
pyenv install $PYTHON_VERSION
# Comprobar si la instalación fue exitosa
if [[ $? -ne 0 ]]; then
echo "❌ Error durante la instalación de Python $PYTHON_VERSION."
exit 1
fi
fi
# Establecer la versión global de Python con pyenv
echo "Configurando Python $PYTHON_VERSION como versión global..."
pyenv global $PYTHON_VERSION
# Actualizar pip a la última versión
echo "Actualizando pip..."
pip install --upgrade pip
# Verificar la instalación
echo "Verificando la instalación..."
python --version
pip --version
# Recargar .bashrc para aplicar los cambios
echo "Recargando .bashrc para aplicar los cambios de pyenv..."
source ~/.bashrc
echo "✅ Python $PYTHON_VERSION configurado como versión global exitosamente."
+27
View File
@@ -0,0 +1,27 @@
#!/bin/bash
# Actualizar repositorios
echo "Actualizando repositorios..."
apt-get update
# Instalar Python 3 y pip
echo "Instalando Python 3 y pip..."
apt-get install -y python3 python3-pip
# Crear alias para 'python' si no existe
if ! command -v python &> /dev/null
then
echo "Creando alias para 'python'..."
ln -s /usr/bin/python3 /usr/bin/python
fi
# Actualizar pip a la última versión
echo "Actualizando pip..."
python3 -m pip install --upgrade pip --break-system-packages
# Verificar la instalación
echo "Verificando la instalación..."
python --version
pip --version
echo "Instalación completada exitosamente."
+24
View File
@@ -0,0 +1,24 @@
#!/bin/bash
# Actualiza los repositorios y asegura que curl esté instalado
apt-get update
apt-get install -y curl
# Verifica las versiones instaladas
echo "Node.js version:"
node -v
echo "npm version:"
npm -v
# Crea un directorio para el proyecto
mkdir "frontend"
cd "frontend"
# Inicializa un nuevo proyecto React
npx create-react-app .
# Instala Material-UI y sus dependencias
npm install @mui/material @emotion/react @emotion/styled
# Inicia el servidor de desarrollo
npm start
+17
View File
@@ -0,0 +1,17 @@
#!/bin/bash
# Actualizar repositorios
echo "Actualizando repositorios..."
apt-get update
# Instalar venv si no está disponible
if ! python3 -m venv --help &> /dev/null; then
echo "Instalando venv..."
apt-get install -y python3-venv
fi
# Crear un entorno virtual llamado 'venv'
echo "Creando entorno virtual 'venv'..."
python3 -m venv /app/venv
echo "Entorno virtual 'venv' creado exitosamente."
+618
View File
@@ -0,0 +1,618 @@
#!/bin/sh
set -eu
# code-server's automatic install script.
# See https://coder.com/docs/code-server/latest/install
usage() {
arg0="$0"
if [ "$0" = sh ]; then
arg0="curl -fsSL https://code-server.dev/install.sh | sh -s --"
else
not_curl_usage="The latest script is available at https://code-server.dev/install.sh
"
fi
cath << EOF
Installs code-server.
It tries to use the system package manager if possible.
After successful installation it explains how to start using code-server.
Pass in user@host to install code-server on user@host over ssh.
The remote host must have internet access.
${not_curl_usage-}
Usage:
$arg0 [--dry-run] [--version X.X.X] [--edge] [--method detect] \
[--prefix ~/.local] [--rsh ssh] [user@host]
--dry-run
Echo the commands for the install process without running them.
--version X.X.X
Install a specific version instead of the latest.
--edge
Install the latest edge version instead of the latest stable version.
--method [detect | standalone]
Choose the installation method. Defaults to detect.
- detect detects the system package manager and tries to use it.
Full reference on the process is further below.
- standalone installs a standalone release archive into ~/.local
Add ~/.local/bin to your \$PATH to use it.
--prefix <dir>
Sets the prefix used by standalone release archives. Defaults to ~/.local
The release is unarchived into ~/.local/lib/code-server-X.X.X
and the binary symlinked into ~/.local/bin/code-server
To install system wide pass --prefix=/usr/local
--rsh <bin>
Specifies the remote shell for remote installation. Defaults to ssh.
The detection method works as follows:
- Debian, Ubuntu, Raspbian: install the deb package from GitHub.
- Fedora, CentOS, RHEL, openSUSE: install the rpm package from GitHub.
- Arch Linux: install from the AUR (which pulls releases from GitHub).
- FreeBSD, Alpine: install from npm.
- macOS: install using Homebrew if installed otherwise install from GitHub.
- All others: install the release from GitHub.
We only build releases on GitHub for amd64 and arm64 on Linux and amd64 for
macOS. When the detection method tries to pull a release from GitHub it will
fall back to installing from npm when there is no matching release for the
system's operating system and architecture.
The standalone method will force installion using GitHub releases. It will not
fall back to npm so on architectures without pre-built releases this will error.
The installer will cache all downloaded assets into ~/.cache/code-server
More installation docs are at https://coder.com/docs/code-server/latest/install
EOF
}
echo_latest_version() {
if [ "${EDGE-}" ]; then
version="$(curl -fsSL https://api.github.com/repos/coder/code-server/releases | awk 'match($0,/.*"html_url": "(.*\/releases\/tag\/.*)".*/)' | head -n 1 | awk -F '"' '{print $4}')"
else
# https://gist.github.com/lukechilds/a83e1d7127b78fef38c2914c4ececc3c#gistcomment-2758860
version="$(curl -fsSLI -o /dev/null -w "%{url_effective}" https://github.com/coder/code-server/releases/latest)"
fi
version="${version#https://github.com/coder/code-server/releases/tag/}"
version="${version#v}"
echo "$version"
}
echo_npm_postinstall() {
echoh
cath << EOF
npm package has been installed.
Extend your path to use code-server:
PATH="$NPM_BIN_DIR:\$PATH"
Then run with:
code-server
EOF
}
echo_standalone_postinstall() {
echoh
cath << EOF
Standalone release has been installed into $STANDALONE_INSTALL_PREFIX/lib/code-server-$VERSION
Extend your path to use code-server:
PATH="$STANDALONE_INSTALL_PREFIX/bin:\$PATH"
Then run with:
code-server
EOF
}
echo_brew_postinstall() {
echoh
cath << EOF
Brew release has been installed.
Run with:
code-server
EOF
}
echo_systemd_postinstall() {
echoh
cath << EOF
$1 package has been installed.
To have systemd start code-server now and restart on boot:
sudo systemctl enable --now code-server@\$USER
Or, if you don't want/need a background service you can run:
code-server
EOF
}
echo_coder_postinstall() {
echoh
echoh "Deploy code-server for your team with Coder: https://github.com/coder/coder"
}
main() {
if [ "${TRACE-}" ]; then
set -x
fi
unset \
DRY_RUN \
METHOD \
OPTIONAL \
ALL_FLAGS \
RSH_ARGS \
EDGE \
RSH
ALL_FLAGS=""
while [ "$#" -gt 0 ]; do
case "$1" in
-*)
ALL_FLAGS="${ALL_FLAGS} $1"
;;
esac
case "$1" in
--dry-run)
DRY_RUN=1
;;
--method)
METHOD="$(parse_arg "$@")"
shift
;;
--method=*)
METHOD="$(parse_arg "$@")"
;;
--prefix)
STANDALONE_INSTALL_PREFIX="$(parse_arg "$@")"
shift
;;
--prefix=*)
STANDALONE_INSTALL_PREFIX="$(parse_arg "$@")"
;;
--version)
VERSION="$(parse_arg "$@")"
shift
;;
--version=*)
VERSION="$(parse_arg "$@")"
;;
--edge)
EDGE=1
;;
--rsh)
RSH="$(parse_arg "$@")"
shift
;;
--rsh=*)
RSH="$(parse_arg "$@")"
;;
-h | --h | -help | --help)
usage
exit 0
;;
--)
shift
# We remove the -- added above.
ALL_FLAGS="${ALL_FLAGS% --}"
RSH_ARGS="$*"
break
;;
-*)
echoerr "Unknown flag $1"
echoerr "Run with --help to see usage."
exit 1
;;
*)
RSH_ARGS="$*"
break
;;
esac
shift
done
if [ "${RSH_ARGS-}" ]; then
RSH="${RSH-ssh}"
echoh "Installing remotely with $RSH $RSH_ARGS"
curl -fsSL https://code-server.dev/install.sh | prefix "$RSH_ARGS" "$RSH" "$RSH_ARGS" sh -s -- "$ALL_FLAGS"
return
fi
METHOD="${METHOD-detect}"
if [ "$METHOD" != detect ] && [ "$METHOD" != standalone ]; then
echoerr "Unknown install method \"$METHOD\""
echoerr "Run with --help to see usage."
exit 1
fi
# These are used by the various install_* functions that make use of GitHub
# releases in order to download and unpack the right release.
CACHE_DIR=$(echo_cache_dir)
STANDALONE_INSTALL_PREFIX=${STANDALONE_INSTALL_PREFIX:-$HOME/.local}
VERSION=${VERSION:-$(echo_latest_version)}
# These can be overridden for testing but shouldn't normally be used as it can
# result in a broken code-server.
OS=${OS:-$(os)}
ARCH=${ARCH:-$(arch)}
distro_name
# Standalone installs by pulling pre-built releases from GitHub.
if [ "$METHOD" = standalone ]; then
if has_standalone; then
install_standalone
echo_coder_postinstall
exit 0
else
echoerr "There are no standalone releases for $ARCH"
echoerr "Please try again without '--method standalone'"
exit 1
fi
fi
# DISTRO can be overridden for testing but shouldn't normally be used as it
# can result in a broken code-server.
DISTRO=${DISTRO:-$(distro)}
case $DISTRO in
# macOS uses brew when available and falls back to standalone. We only have
# amd64 for macOS so for anything else use npm.
macos)
BREW_PATH="${BREW_PATH-brew}"
if command_exists "$BREW_PATH"; then
install_brew
else
echoh "Homebrew not installed."
echoh "Falling back to standalone installation."
npm_fallback install_standalone
fi
;;
# The .deb and .rpm files are pulled from GitHub and we only have amd64 and
# arm64 there and need to fall back to npm otherwise.
debian) npm_fallback install_deb ;;
fedora | opensuse) npm_fallback install_rpm ;;
# Arch uses the AUR package which only supports amd64 and arm64 since it
# pulls releases from GitHub so we need to fall back to npm.
arch) npm_fallback install_aur ;;
# We don't have GitHub releases that work on Alpine or FreeBSD so we have no
# choice but to use npm here.
alpine | freebsd) install_npm ;;
# For anything else we'll try to install standalone but fall back to npm if
# we don't have releases for the architecture.
*)
echoh "Unsupported package manager."
echoh "Falling back to standalone installation."
npm_fallback install_standalone
;;
esac
echo_coder_postinstall
}
parse_arg() {
case "$1" in
*=*)
# Remove everything after first equal sign.
opt="${1%%=*}"
# Remove everything before first equal sign.
optarg="${1#*=}"
if [ ! "$optarg" ] && [ ! "${OPTIONAL-}" ]; then
echoerr "$opt requires an argument"
echoerr "Run with --help to see usage."
exit 1
fi
echo "$optarg"
return
;;
esac
case "${2-}" in
"" | -*)
if [ ! "${OPTIONAL-}" ]; then
echoerr "$1 requires an argument"
echoerr "Run with --help to see usage."
exit 1
fi
;;
*)
echo "$2"
return
;;
esac
}
fetch() {
URL="$1"
FILE="$2"
if [ -e "$FILE" ]; then
echoh "+ Reusing $FILE"
return
fi
sh_c mkdir -p "$CACHE_DIR"
sh_c curl \
-#fL \
-o "$FILE.incomplete" \
-C - \
"$URL"
sh_c mv "$FILE.incomplete" "$FILE"
}
install_brew() {
echoh "Installing latest from Homebrew."
echoh
sh_c "$BREW_PATH" install code-server
echo_brew_postinstall
}
install_deb() {
echoh "Installing v$VERSION of the $ARCH deb package from GitHub."
echoh
fetch "https://github.com/coder/code-server/releases/download/v$VERSION/code-server_${VERSION}_$ARCH.deb" \
"$CACHE_DIR/code-server_${VERSION}_$ARCH.deb"
sudo_sh_c dpkg -i "$CACHE_DIR/code-server_${VERSION}_$ARCH.deb"
echo_systemd_postinstall deb
}
install_rpm() {
echoh "Installing v$VERSION of the $ARCH rpm package from GitHub."
echoh
fetch "https://github.com/coder/code-server/releases/download/v$VERSION/code-server-$VERSION-$ARCH.rpm" \
"$CACHE_DIR/code-server-$VERSION-$ARCH.rpm"
sudo_sh_c rpm -U "$CACHE_DIR/code-server-$VERSION-$ARCH.rpm"
echo_systemd_postinstall rpm
}
install_aur() {
echoh "Installing latest from the AUR."
echoh
sh_c mkdir -p "$CACHE_DIR/code-server-aur"
sh_c "curl -#fsSL https://aur.archlinux.org/cgit/aur.git/snapshot/code-server.tar.gz | tar -xzC $CACHE_DIR/code-server-aur --strip-components 1"
echo "+ cd $CACHE_DIR/code-server-aur"
if [ ! "${DRY_RUN-}" ]; then
cd "$CACHE_DIR/code-server-aur"
fi
sh_c makepkg -si --noconfirm
echo_systemd_postinstall AUR
}
install_standalone() {
echoh "Installing v$VERSION of the $ARCH release from GitHub."
echoh
fetch "https://github.com/coder/code-server/releases/download/v$VERSION/code-server-$VERSION-$OS-$ARCH.tar.gz" \
"$CACHE_DIR/code-server-$VERSION-$OS-$ARCH.tar.gz"
# -w only works if the directory exists so try creating it first. If this
# fails we can ignore the error as the -w check will then swap us to sudo.
sh_c mkdir -p "$STANDALONE_INSTALL_PREFIX" 2> /dev/null || true
sh_c="sh_c"
if [ ! -w "$STANDALONE_INSTALL_PREFIX" ]; then
sh_c="sudo_sh_c"
fi
if [ -e "$STANDALONE_INSTALL_PREFIX/lib/code-server-$VERSION" ]; then
echoh
echoh "code-server-$VERSION is already installed at $STANDALONE_INSTALL_PREFIX/lib/code-server-$VERSION"
echoh "Remove it to reinstall."
exit 0
fi
"$sh_c" mkdir -p "$STANDALONE_INSTALL_PREFIX/lib" "$STANDALONE_INSTALL_PREFIX/bin"
"$sh_c" tar -C "$STANDALONE_INSTALL_PREFIX/lib" -xzf "$CACHE_DIR/code-server-$VERSION-$OS-$ARCH.tar.gz"
"$sh_c" mv -f "$STANDALONE_INSTALL_PREFIX/lib/code-server-$VERSION-$OS-$ARCH" "$STANDALONE_INSTALL_PREFIX/lib/code-server-$VERSION"
"$sh_c" ln -fs "$STANDALONE_INSTALL_PREFIX/lib/code-server-$VERSION/bin/code-server" "$STANDALONE_INSTALL_PREFIX/bin/code-server"
echo_standalone_postinstall
}
install_npm() {
echoh "Installing v$VERSION from npm."
echoh
NPM_PATH="${YARN_PATH-npm}"
if command_exists "$NPM_PATH"; then
sh_c="sh_c"
if [ ! "${DRY_RUN-}" ] && [ ! -w "$(NPM_PATH config get prefix)" ]; then
sh_c="sudo_sh_c"
fi
echoh "Installing with npm."
echoh
"$sh_c" "$NPM_PATH" install -g "code-server@$VERSION" --unsafe-perm
NPM_BIN_DIR="\$($NPM_PATH bin -g)" echo_npm_postinstall
return
fi
echoerr "Please install npm to install code-server!"
echoerr "You will need at least node v20 and a few C dependencies."
echoerr "See the docs https://coder.com/docs/code-server/latest/install#npm"
exit 1
}
# Run $1 if we have a standalone otherwise run install_npm.
npm_fallback() {
if has_standalone; then
$1
else
echoh "No standalone releases for $ARCH."
echoh "Falling back to installation from npm."
install_npm
fi
}
# Determine if we have standalone releases on GitHub for the system's arch.
has_standalone() {
case $ARCH in
arm64) return 0 ;;
# We only have arm64 for macOS.
amd64)
[ "$(distro)" != macos ]
return
;;
*) return 1 ;;
esac
}
os() {
uname="$(uname)"
case $uname in
Linux) echo linux ;;
Darwin) echo macos ;;
FreeBSD) echo freebsd ;;
*) echo "$uname" ;;
esac
}
# Print the detected Linux distro, otherwise print the OS name.
#
# Example outputs:
# - macos -> macos
# - freebsd -> freebsd
# - ubuntu, raspbian, debian ... -> debian
# - amzn, centos, rhel, fedora, ... -> fedora
# - opensuse-{leap,tumbleweed} -> opensuse
# - alpine -> alpine
# - arch, manjaro, endeavouros, ... -> arch
#
# Inspired by https://github.com/docker/docker-install/blob/26ff363bcf3b3f5a00498ac43694bf1c7d9ce16c/install.sh#L111-L120.
distro() {
if [ "$OS" = "macos" ] || [ "$OS" = "freebsd" ]; then
echo "$OS"
return
fi
if [ -f /etc/os-release ]; then
(
. /etc/os-release
if [ "${ID_LIKE-}" ]; then
for id_like in $ID_LIKE; do
case "$id_like" in debian | fedora | opensuse | arch)
echo "$id_like"
return
;;
esac
done
fi
echo "$ID"
)
return
fi
}
# Print a human-readable name for the OS/distro.
distro_name() {
if [ "$(uname)" = "Darwin" ]; then
echo "macOS v$(sw_vers -productVersion)"
return
fi
if [ -f /etc/os-release ]; then
(
. /etc/os-release
echo "$PRETTY_NAME"
)
return
fi
# Prints something like: Linux 4.19.0-9-amd64
uname -sr
}
arch() {
uname_m=$(uname -m)
case $uname_m in
aarch64) echo arm64 ;;
x86_64) echo amd64 ;;
*) echo "$uname_m" ;;
esac
}
command_exists() {
if [ ! "$1" ]; then return 1; fi
command -v "$@" > /dev/null
}
sh_c() {
echoh "+ $*"
if [ ! "${DRY_RUN-}" ]; then
sh -c "$*"
fi
}
sudo_sh_c() {
if [ "$(id -u)" = 0 ]; then
sh_c "$@"
elif command_exists doas; then
sh_c "doas $*"
elif command_exists sudo; then
sh_c "sudo $*"
elif command_exists su; then
sh_c "su root -c '$*'"
else
echoh
echoerr "This script needs to run the following command as root."
echoerr " $*"
echoerr "Please install doas, sudo, or su."
exit 1
fi
}
echo_cache_dir() {
if [ "${XDG_CACHE_HOME-}" ]; then
echo "$XDG_CACHE_HOME/code-server"
elif [ "${HOME-}" ]; then
echo "$HOME/.cache/code-server"
else
echo "/tmp/code-server-cache"
fi
}
echoh() {
echo "$@" | humanpath
}
cath() {
humanpath
}
echoerr() {
echoh "$@" >&2
}
# humanpath replaces all occurrences of " $HOME" with " ~"
# and all occurrences of '"$HOME' with the literal '"$HOME'.
humanpath() {
sed "s# $HOME# ~#g; s#\"$HOME#\"\$HOME#g"
}
# We need to make sure we exit with a non zero exit if the command fails.
# /bin/sh does not support -o pipefail unfortunately.
prefix() {
PREFIX="$1"
shift
fifo="$(mktemp -d)/fifo"
mkfifo "$fifo"
sed -e "s#^#$PREFIX: #" "$fifo" &
"$@" > "$fifo" 2>&1
}
main "$@"
View File
+80
View File
@@ -0,0 +1,80 @@
import os
import uuid
import shutil
import json
import subprocess
import hashlib
from datetime import datetime
# Archivo JSON para guardar los datos de los contenedores
CONTAINER_DATA_FILE = 'containers.json'
# Nombre y etiqueta para la imagen base
BASE_IMAGE_TAG = 'alpine_vscode:latest'
CONTENEDOR_IDENTIFICADOR = "easily-sound-ant"
# -------------------------------
# Función: Eliminar un contenedor por ID o nombre y actualizar el JSON
# -------------------------------
def delete_container(identifier):
if not os.path.exists(CONTAINER_DATA_FILE):
print("❌ No hay archivo JSON de contenedores.")
return
with open(CONTAINER_DATA_FILE, 'r') as file:
containers = json.load(file)
# Determinar si el identificador es un ID o un nombre
container = next((c for c in containers if c['id'] == identifier or c['name'] == identifier), None)
if not container:
print(f"❌ No se encontró ningún contenedor con ID o nombre: {identifier} en el JSON.")
return
try:
# Comprobar si el contenedor existe realmente en Docker
result = subprocess.getoutput(f"docker ps -a -q -f id={container['id']}")
if not result:
print(f"⚠️ El contenedor {container['name']} ya no existe en Docker. Eliminando del JSON...")
else:
# Eliminar el contenedor y su red asociada
print(f"➤ Eliminando contenedor: {container['name']} con ID: {container['id']}")
os.system(f"docker rm -f {container['id']}")
print(f"➤ Eliminando red: {container['network']}")
os.system(f"docker network rm {container['network']}")
# Actualizar el JSON excluyendo el contenedor eliminado
containers = [c for c in containers if c['id'] != container['id']]
with open(CONTAINER_DATA_FILE, 'w') as file:
json.dump(containers, file, indent=4)
print(f"✔ Contenedor {container['name']} eliminado correctamente.")
except Exception as e:
print(f"❌ Error eliminando el contenedor {container['name']}: {e}")
# -------------------------------
# Función: Limpiar imágenes huérfanas
# -------------------------------
def clean_unused_images():
print("➤ Eliminando imágenes huérfanas...")
os.system('docker image prune -f')
# -------------------------------
# Función: Limpiar redes huérfanas
# -------------------------------
def clean_unused_networks():
print("➤ Eliminando redes huérfanas...")
os.system('docker network prune -f')
if __name__ == "__main__":
identifier = CONTENEDOR_IDENTIFICADOR
if identifier:
delete_container(identifier)
# Limpiar imágenes y redes huérfanas
clean_unused_images()
clean_unused_networks()
else:
print("❌ No se ingresó ningún ID o nombre.")
+89
View File
@@ -0,0 +1,89 @@
import os
import uuid
import shutil
import json
import subprocess
import hashlib
from datetime import datetime
# Archivo JSON para guardar los datos de los contenedores
CONTAINER_DATA_FILE = 'containers.json'
# Nombre y etiqueta para la imagen base
BASE_IMAGE_TAG = 'alpine_vscode:latest'
# -------------------------------
# Función: Eliminar todos los contenedores listados en el JSON
# -------------------------------
def delete_all_containers():
if not os.path.exists(CONTAINER_DATA_FILE):
print("❌ No hay contenedores para eliminar.")
return
with open(CONTAINER_DATA_FILE, 'r') as file:
containers = json.load(file)
if not containers:
print("❌ No hay contenedores listados en el archivo JSON.")
return
# Lista para los contenedores que no pudieron eliminarse
remaining_containers = []
# Eliminar contenedores y redes
for container in containers:
try:
# Comprobar si el contenedor existe realmente
result = subprocess.getoutput(f"docker ps -a -q -f id={container['id']}")
if not result:
print(f"⚠️ El contenedor {container['name']} ya no existe. Eliminando del JSON...")
else:
print(f"➤ Eliminando contenedor: {container['name']} con ID: {container['id']}")
os.system(f"docker rm -f {container['id']}")
print(f"➤ Eliminando red: {container['network']}")
os.system(f"docker network rm {container['network']}")
except Exception as e:
print(f"❌ Error eliminando el contenedor {container['name']}: {e}")
# Guardar el contenedor en la lista si no se pudo eliminar
remaining_containers.append(container)
continue
# Actualizar el archivo JSON solo con los contenedores que no pudieron eliminarse
if remaining_containers:
with open(CONTAINER_DATA_FILE, 'w') as file:
json.dump(remaining_containers, file, indent=4)
print("⚠️ Algunos contenedores no pudieron eliminarse y se mantuvieron en el JSON.")
else:
# Si todos los contenedores fueron eliminados, vaciar el archivo JSON
open(CONTAINER_DATA_FILE, 'w').close()
print("✔ Todos los contenedores y redes han sido eliminados y el archivo JSON ha sido limpiado.")
# -------------------------------
# Función: Limpiar imágenes huérfanas
# -------------------------------
def clean_unused_images():
print("➤ Eliminando imágenes huérfanas...")
os.system('docker image prune -f')
# -------------------------------
# Función: Limpiar redes huérfanas
# -------------------------------
def clean_unused_networks():
print("➤ Eliminando redes huérfanas...")
os.system('docker network prune -f')
##############################################
# Ejecución del script
##############################################
if __name__ == "__main__":
# Eliminar todos los contenedores y redes
delete_all_containers()
clean_unused_images()
clean_unused_networks()
+241
View File
@@ -0,0 +1,241 @@
import os
import uuid
import shutil
import json
import socket
import subprocess
import petname
import hashlib
import platform
from datetime import datetime
# Archivo JSON para guardar los datos de los contenedores
CONTAINER_DATA_FILE = 'containers.json'
# Nombre y etiqueta para la imagen base
BASE_IMAGE_TAG = 'debian_vscode:tag'
#Lita de puertos internos
PUERTOS_INTERNOS = [3000, 5000, 8000, 8080, 17000]
# Numero de conteineres a crear
NUM_CONTAINERS = 1
# -------------------------------
# Función: Comprobar si un puerto está libre con nmap
# -------------------------------
def is_port_available(port):
# Ejecuta nmap para comprobar si el puerto está abierto
command = f"nmap -p {port} 127.0.0.1"
print(f"[INFO] Ejecutando nmap para el puerto {port}...")
result = subprocess.run(command, shell=True, capture_output=True, text=True)
# Muestra el resultado del comando nmap
print(f"[DEBUG] Resultado de nmap para el puerto {port}:\n{result.stdout}")
# Analiza el resultado para ver si el puerto está cerrado
if "closed" in result.stdout:
return True # Puerto libre
else:
return False # Puerto ocupado
# -------------------------------
# Función: Ejecutar contenedor y guardar datos
# -------------------------------
def run_docker_compose(internal_ports=None):
# Genera un UUID único
unique_uuid = str(uuid.uuid4())
# Genera un nombre único para el contenedor
uuid_palabras = petname.Generate(3, separator='-')
# Nombres únicos para el servicio, contenedor y la red
service_name = f"{uuid_palabras}"
container_name = f"{uuid_palabras}"
network_name = f"alpine_network_{unique_uuid}"
# Nombre de la imagen local a usar
image_tag = BASE_IMAGE_TAG # Usar la imagen local directamente
# Nombre del archivo docker-compose nuevo
new_docker_compose_file = f'docker-compose-{unique_uuid}.yml'
try:
# Configuración personalizada de puertos
ports_mapping = []
custom_ports = []
host_port = 27000 # Puerto inicial
print(f"[INFO] Iniciando la configuración de puertos a partir del puerto {host_port}")
if internal_ports:
for internal_port in internal_ports:
print(f"[INFO] Configurando puerto interno: {internal_port}")
# Buscar el siguiente puerto disponible usando nmap
while host_port <= 65000:
if is_port_available(host_port):
print(f"[INFO] Asignando puerto {host_port} para el puerto interno {internal_port}...")
custom_ports.append(f" - \"{host_port}:{internal_port}\"")
ports_mapping.append({
"host_port": host_port,
"internal_port": internal_port
})
host_port += 1 # Incrementa el puerto para el siguiente uso
break
else:
print(f"[WARNING] Puerto {host_port} ocupado, probando el siguiente...")
host_port += 1 # Incrementa si el puerto está ocupado
if host_port > 65000:
raise Exception("Se superó el límite de puertos disponibles.")
custom_ports_yaml = "\n".join(custom_ports)
print(f"[INFO] Puertos personalizados configurados:\n{custom_ports_yaml}")
else:
custom_ports_yaml = "" # No agrega puertos si no se especifican
print("[INFO] No se especificaron puertos internos.")
# Genera el contenido del archivo docker-compose dinámicamente
docker_compose_content = f"""
version: '3.8'
services:
{service_name}:
image: {image_tag} # Usar la imagen base directamente
container_name: {container_name}
networks:
- {network_name}
restart: always
tty: true
volumes:
- ./app:/app
ports:
{custom_ports_yaml}
command: tail -f /dev/null # Mantener activo el contenedor
networks:
{network_name}:
driver: bridge
"""
# Guarda el archivo docker-compose generado
with open(new_docker_compose_file, 'w') as file:
file.write(docker_compose_content)
# Muestra el contenido generado para depuración
print(f"[DEBUG] Contenido del archivo {new_docker_compose_file}:\n")
print(docker_compose_content)
# Ejecuta docker-compose con el archivo nuevo y captura la salida
print("[INFO] Ejecutando docker compose...")
result = subprocess.run(
f'docker compose -f {new_docker_compose_file} up -d --no-build',
shell=True,
capture_output=True,
text=True
)
# Muestra el resultado del comando
if result.returncode != 0:
print(f"[ERROR] Error al ejecutar docker compose:\n{result.stderr}")
raise Exception("Error al ejecutar docker-compose")
else:
print(f"[INFO] Contenedor iniciado exitosamente:\n{result.stdout}")
# Mostrar contenedores activos y detenidos
print("[DEBUG] Contenedores activos y detenidos:")
subprocess.run("docker ps -a", shell=True)
# Obtener el ID del contenedor creado
container_id = subprocess.getoutput(f"docker ps -qf name={container_name}")
if not container_id:
print(f"[ERROR] No se pudo obtener el ID del contenedor {container_name}.")
raise Exception("No se pudo obtener el ID del contenedor")
print(f"[INFO] ID del contenedor: {container_id}")
# Mostrar logs del contenedor si está detenido
print("[INFO] Mostrando logs del contenedor:")
subprocess.run(f"docker logs {container_id}", shell=True)
# Guardar los datos del contenedor en el archivo JSON
save_container_data({
'id': container_id,
'name': container_name,
'network': network_name,
'image': image_tag,
'compose_file': new_docker_compose_file,
'creation_timestamp': datetime.now().isoformat(),
'ports': ports_mapping # Agrega la información de los puertos mapeados
})
except Exception as e:
print(f"[ERROR] Error: {str(e)}")
finally:
# Eliminar el archivo docker-compose generado si existe
if os.path.exists(new_docker_compose_file):
print(f"[INFO] Eliminando archivo temporal: {new_docker_compose_file}")
os.remove(new_docker_compose_file)
# -------------------------------
# Función: Guardar datos del contenedor en JSON
# -------------------------------
def save_container_data(container_data):
# Cargar datos existentes si el archivo existe y no está vacío
if os.path.exists(CONTAINER_DATA_FILE) and os.path.getsize(CONTAINER_DATA_FILE) > 0:
with open(CONTAINER_DATA_FILE, 'r') as file:
try:
data = json.load(file) # Cargar datos existentes
except json.JSONDecodeError:
data = [] # Si hay error al leer, inicializar como lista vacía
else:
# Crear el archivo vacío y usar una lista vacía
with open(CONTAINER_DATA_FILE, 'w') as file:
json.dump([], file)
data = [] # Inicializar como lista vacía
# Agregar nuevo contenedor
data.append(container_data)
# Guardar datos actualizados
with open(CONTAINER_DATA_FILE, 'w') as file:
json.dump(data, file, indent=4)
# -------------------------------
# Función: Limpiar imágenes huérfanas
# -------------------------------
def clean_unused_images():
print("➤ Eliminando imágenes huérfanas...")
os.system('docker image prune -f')
# -------------------------------
# Función: Limpiar redes huérfanas
# -------------------------------
def clean_unused_networks():
print("➤ Eliminando redes huérfanas...")
os.system('docker network prune -f')
######################################### -------------------------------
# Ejecución del script
######################################### -------------------------------
if __name__ == "__main__":
# Crear contenedores y guardarlos en el JSON
for _ in range(NUM_CONTAINERS):
run_docker_compose(internal_ports=PUERTOS_INTERNOS)
print("➤ Contenedores creados y guardados en el JSON")
# Limpiar imágenes huérfanas
clean_unused_images()
# Limpiar redes huérfanas
clean_unused_networks()