Skip to content

Instantly share code, notes, and snippets.

@jrgavilanes
Last active March 26, 2025 09:46
Show Gist options
  • Select an option

  • Save jrgavilanes/1929d11ec7cbbcf5548ddc86741ad38d to your computer and use it in GitHub Desktop.

Select an option

Save jrgavilanes/1929d11ec7cbbcf5548ddc86741ad38d to your computer and use it in GitHub Desktop.
notas de ubuntu server

Ubuntu Server (14.04): Buenas prácticas de configuración

by Juan Ramón Gavilanes (jrgavilanes@gmail.com)

Índice.

1.- Configuración inicial con Ubuntu Server

1.1.- Login como root.

local$: ssh root@SERVER_IP_ADDRESS

¿Quieres saber más sobre cómo conectar con tu servidor con SSH?

1.2.- Crear nuevo usuario y escalarlo.

# adduser janrax
# gpasswd -a janrax sudo

Si queremos volver a cambiar la clave de usuario, escribiremos:

# sudo passwd janrax

1.3.- Añadir clave pública de autentificación.

Genera par de claves en tu máquina local ( si no tienes ninguna todavía )

local$: ssh-keygen -t rsa -b 4096

Asumiendo que su usuario es localuser está será la salida generada por el comando:

ssh-keygen output
Generating public/private rsa key pair.
Enter file in which to save the key (/Users/localuser/.ssh/id_rsa):

Recuerda que no hay que compartir la clave privada con nadie!!

Después de generar el par de claves SSH, debes copiar la clave pública a tu nuevo servidor.

local$: ssh-copy-id janrax@SERVER_IP_ADDRESS

1.4.- Configurar demonio SSH: eliminar acceso de root.

En el servidor y conectados como root, editarmos el archivo de configuración de SSH y bloqueamos el acceso de root por ssh.

vi /etc/ssh/sshd_config
/etc/ssh/sshd_config
PermitRootLogin no

Si queremos forzar la conexión ssh usando sólo claves privadas, evitando por tanto, la conexión por password abierto, deberemos cambiar el siguiente parámetro:
/etc/ssh/sshd_config
PasswordAuthentication no

Tras realizar las modificaciones deseadas, salvamos y reiniciamos el servicio # service ssh restart

Antes de desconectar nuestra sesión como root, abrimos otro terminal y comprobamos que el nuevo usuario conecta correctamente. Si necesitamos escalar privilegios con el nuevo usuario, sólo debemos incluir la palabra sudo al inicio del comando.


Combo: Si además queremos proteger nuestra conexión de SSH de ataques de fuerza bruta, podemos instalar fail2ban:

sudo apt-get update
sudo apt-get install fail2ban

sudo systemctl start fail2ban
sudo systemctl enable fail2ban
sudo fail2ban-client status

Por defecto, baneará (expulsará:) 10 minutos al usuario que se equivoque 3 veces al introducir su password en un período de 10 minutos.

¿Quieres saber más sobre cómo proteger SSH?

1.5.- Configurando un firewall básico.

Ubuntu incorpora de serie una herramienta llamada ufw, para configurar las políticas de firewall. Nuestra estrategia básica será bloquear por defecto todo lo que no necesitemos.

El demonio SSH corre por defecto en el puerto 22, y ufw permite referenciarlo por nombre:

sudo ufw allow ssh

En caso en que hayamos modificado el puerto por el que está escuchando, habrá que referenciar el puerto junto con el protocolo:

sudo ufw allow 4444/tcp

Si queremos ejecutar un servidor HTTP convecional, necesitaremos abrir el puerto 80:

sudo ufw allow 80/tcp

Si queremos que el servidor tenga SSL/TSL activado, también deberemos permitir el tráfico en su puerto:

sudo ufw allow 443/tcp

Necesitas correo SMTP?

sudo ufw allow 25/tcp

Quieres cerrar un puerto abierto?

sudo deny 25/tcp

Una vez tengamos las excepciones, las podemos revisar escribiendo:

sudo ufw show added

Si todo está ok, podemos activar el firewall escribiendo:

sudo ufw enable

Este comando bloqueará el tráfico a los puertos, instalará las excepciones que hemos indicado y configurará el servicio para que arranque automáticamente siempre que lo haga el servidor.

¿Quieres saber más sobre configuración avanzada del firewall?

1.6.- Configurar zonas horarias y sincronización __N__etwork __T__ime __P__rotocol.

Ejecuta el siguiente comando para establecer la zona horaria que quieres para el servidor.

sudo dpkg-reconfigure tzdata

Alternativa para configurar hora por comando desatendido

echo "Europe/Madrid" > /etc/timezone && ln -sf /usr/share/zoneinfo/Europe/Madrid /etc/localtime

Configurar sincronización NTP, para sincronizar la hora con otros servidores de Internet.

sudo apt-get update
sudo apt-get install ntp

¿Quieres saber más sobre NTP?

1.7.- Crear un archivo SWAP.

El tamaño que debe tener un espacio SWAP depende de la situación, pero el doble de la memoria RAM disponible es un buen punto de partida. Si queremos que tenga __4 G__igas este es el comando a ejecutar:

sudo fallocate -l 4G /swapfile

Restringimos el acceso para que otros usuarios o procesos no puedan afectarle

sudo chmod 600 /swapfile

Formateamos el archivo como swap

sudo mkswap /swapfile

Lo activamos

sudo swapon /swapfile

Guardamos configuración para que inicie automáticamente al arrancar el sistema.

sudo sh -c 'echo "/swapfile none swap sw 0 0" >> /etc/fstab'

1.8.- Bibliografía.

2.- Servidores Web

2.1.- Nginx.

Instalación:

sudo apt-get update
sudo apt-get install nginx

Comprobamos el acceso desde el navegador web. Si necesitamos la dirección pública de la máquina, ejecutamos:

ip addr show eth0 | grep inet | awk '{ print $2; }' | sed 's/\/.*$//'

Manejando el proceso Nginx:

Detener el servidor web:

sudo service nginx stop

Arrancar el servidor web:

sudo service nginx start

Reiniciar el servidor web:

sudo service nginx restart

Nos aseguramos que el servidor web iniciará automáticamente al arrancar el servidor:

sudo update-rc.d nginx defaults

Configuramos el directorio Document root, que por defecto, está en /usr/share/nginx/html para dejarlo en /var/www

//En este ejemplo configuramos la esctructura de directorio para alojar dos sitios web.
sudo mkdir -p /var/www/example.com/html
sudo mkdir -p /var/www/test.com/html
//Le damos privilegios a nuestro usuario regular.
sudo chown -R $USER:$USER /var/www/example.com/html
sudo chown -R $USER:$USER /var/www/test.com/html
//Aseguramos que los permisos de la raíz sean los correctos.
sudo chmod -R 755 /var/www

Creamos los archivos Server Block

sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/example.com

Editamos el nuevo archivo example.com, y lo dejamos así:

server {
    listen 80 default_server;
    listen [::]:80 default_server ipv6only=on;

    root /var/www/example.com/html;
    index index.html index.htm;

    server_name example.com www.example.com;

    location / {
        try_files $uri $uri/ =404;
    }
}

Activamos el nuevo Server Block y reiniciamos el servidor.

sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/

Ya estaríamos sirviendo nuestro nuevo sitio web, sin embargo, nos queda por hacer unos sencillos ajustes:

//Eliminamos el enlace del sitio que se crea por defecto.
sudo rm /etc/nginx/sites-enabled/default

Descomentamos un parámetro en el archivo de configuración de nginx

/etc/nginx/nginx.conf
server_names_hash_bucket_size 64;

Reiniciamos nginx ``` sudo service nginx restart ```

Por defecto el archivo LOG se almacena en:

/var/log/nginx/error.log

2.2.- Mysql y PHP.

Instalación de MySQL

sudo apt-get update
sudo apt-get install mysql-server
//Generamos la estructura de directorios:
sudo mysql_install_db
//Protegemos la base de datos corriendo este script de seguridad
sudo mysql_secure_installation

Instalación de PHP

sudo apt-get install php5-fpm php5-mysql php5-cli php5-mcrypt
//Si planeamos ejecutar wordpress añadir: ->  php5-gd libssh2-php

Configuramos el archivo de configuración de PHP para hacerlo más seguro. Buscamos el parámetro cgi.fix_pathinfo, lo descomentamos y ponemos su valor a 0.

/etc/php5/fpm/php.ini
cgi.fix_pathinfo=0

Y ahora reiniciamos el procesador PHP ``` sudo service php5-fpm restart ``` #### Configuración de Nginx para usar PHP Abrimos el Server Block del la aplicación que queremos que ejecute PHP, y lo dejamos así, realizando los cambios pertinentes al arrea de __root__, y __server_name__.
sudo vi /etc/nginx/sites-available/default
server {
    listen 80 default_server;
    listen [::]:80 default_server ipv6only=on;

    root /usr/share/nginx/html;
    index index.php index.html index.htm;

    server_name server_domain_name_or_IP;

    location / {
        try_files $uri $uri/ =404;
    }

    error_page 404 /404.html;
    error_page 500 502 503 504 /50x.html;
    location = /50x.html {
        root /usr/share/nginx/html;
    }

    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass unix:/var/run/php5-fpm.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }
}

Reiniciamos el servicio

sudo service nginx restart

Probamos el servidor cargando un archivo .php con la función phpinfo();

2.3.- Bibliografía.

3.- Otras aplicaciones

3.1.- Node Js.

Hay varios métodos, ver bibliografía, pero el que más me ha gustado es instalarlo a través de NVM, ya que permite tener varios sistemas instalados y elegir cual usar.

Se instala así:

sudo apt-get update
sudo apt-get install build-essential libssl-dev

Ahora hay que obtener el script de instalación más actual desde la página github del desarrollador. A día de hoy el siguiente script es el más actual:

curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.29.0/install.sh | bash

Una vez instalado, cerramos la sesión y la volvemos a arrancar.

El siguiente comando nos permite elegir que versión de node queremos instalar:

nvm ls-remote
...
    iojs-v3.0.0
    iojs-v3.1.0
    iojs-v3.2.0
    iojs-v3.3.0
    iojs-v3.3.1
         v4.0.0
         v4.1.0
         v4.1.1
         v4.1.2
         v4.2.0

Si queremos instalar la última en nuestro sistema, ejecutamos:

nvm install 4.2.0

Para ver la versión de node que estamos usando ahora mismo escribimos:

node -v

Para ver las versiones que tenemos instaladas en nuestro sistema:

nvm ls

Para cambiar a otra versión que tengamos instalada:

nvm use 0.11.13

Para establecer una versión por defecto:

nvm alias default 4.2.0
nvm use default

3.2.- Wordpress.

3.3.- Laravel.

Preparación:

sudo apt-get update && apt-get upgrade

Instalación

sudo apt-get install php5-fpm php5-mysql php5-cli php5-mcrypt

Configuramos Nginx

sudo mkdir /var/www/laravel
sudo vi /etc/nginx/sites-available/laravel

Y copiamos esto:

server {
        listen 80;

        root /var/www/laravel/public/;
        index index.php index.html index.htm;

        server_name laravel.jrgware.test www.laravel.jrgware.test;

        location / {
             try_files $uri $uri/ /index.php$is_args$args;
        }

        # pass the PHP scripts to FastCGI server listening on /var/run/php5-fpm.sock
        location ~ \.php$ {
                try_files $uri /index.php =404;
                fastcgi_pass unix:/var/run/php5-fpm.sock;
                fastcgi_index index.php;
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                include fastcgi_params;
        }
}

Activamos el sitio:

sudo ln -s /etc/nginx/sites-available/laravel /etc/nginx/sites-enabled/

Configuramos PHP

Editamos su archivo de configuración:

sudo vi  /etc/php5/fpm/php.ini

Buscamos la linea cgi.fix_pathinfo y la dejamos así:

cgi.fix_pathinfo=0

Ahora editamos:

sudo vi /etc/php5/fpm/pool.d/www.conf

Si existe esta linea:

listen = 127.0.0.1:9000

la sustituimos por esta:

listen = /var/run/php5-fpm.sock

Salvamos todos los cambios y reiniciamos servicios:

sudo service php5-fpm restart
sudo service nginx restart

Configuramos Composer

sudo curl -sS https://getcomposer.org/installer | php
sudo mv composer.phar /usr/local/bin/composer

Ya podemos instalar Laravel

sudo composer create-project laravel/laravel /var/www/laravel/

Para finalizar establecemos los permisos de la carpeta

sudo chgrp -R www-data /var/www/laravel
sudo chmod -R 775 /var/www/laravel/storage

3.4.- Bibliografía.

4.- Seguridad

4.1.- Actualizar sistema

$ sudo apt-get update
$ sudo apt-get upgrade
$ sudo shutdown -r now //reiniciar servidor.

4.2.- Crear e instalar certificado SSL

$ sudo mkdir /etc/nginx/ssl
$ sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/nginx/ssl/nginx.key -out /etc/nginx/ssl/nginx.crt
//el campo más importante es (e.g. server FQDN or YOUR name), que debe ser el nombre del dominio o la ip pública del servidor.

// /etc/nginx/sites-available/my-server-block
server {
        listen 80 default_server;
        listen [::]:80 default_server ipv6only=on;

        listen 443 ssl;                                              // <-- Línea añadida

        root /usr/share/nginx/html;
        index index.html index.htm;

        server_name your_domain.com;
        ssl_certificate /etc/nginx/ssl/nginx.crt;           // <-- Línea añadida
        ssl_certificate_key /etc/nginx/ssl/nginx.key;  // <-- Línea añadida

        location / {
                try_files $uri $uri/ =404;
        }
}

$ sudo service nginx restart

Para que nuestro certificado esté avalado por una entidad y no muestre mensajes preocupantes en los navegadores, podemos usar los servicios de Let's Encrypt, mirar en bibliografía el articulo que lo explica detalladamente.

4.3.- Bibliografía

5.- Otros

5.1.- Chequear velocidad de internet desde la terminal

$ wget -O speedtest-cli https://raw.github.com/sivel/speedtest-cli/master/speedtest_cli.py
$ chmod +x speedtest-cli
$ ./speedtest-cli

5.2.- Listar el total de paquetes instalados

Utilizamos el siguiente comando:

dpkg --get-selections

Gracias a este herramienta también es posible exportar la lista de paquetes instalados:

dpkg --get-selections > mis_paquetes

Luego podemos instalarlos en otra máquina:

dpkg --set-selections < mis_paquetes
apt-get dselect-upgrade

El comando dpkg –l da la lista de paquetes instalados pero con mayor información. Sin embargo, no es posible utilizarlo para instalar una lista de paquetes.

5.3.- Mi Bibliografía

Mi Manual Digital Ocean

Repositorio configuraciones

5.4- Iniciamos automáticamente contenedores o servicios al iniciar el sistema (autoexec.bat)

file: /etc/rc.local

#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.


docker start rstudio1 && docker exec -it rstudio1 bash arrancaservicios.sh
docker start rstudio2

exit 0

5.5 SSH server y Networking

instalar

$ sudo apt-get install openssh-server

Pon IP estática al servidor

$ ifconfig -a
...
enp0s8: flags=4098<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        ether 08:00:27:e5:78:0f  txqueuelen 1000  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
 ...

$ cat /etc/network/interfaces
auto lo
iface lo inet loopback

auto enp0s8
iface enp0s8 inet static
address 192.168.56.100

Poner nombre del host

$ cat /etc/hostname 
apihub

Lista de hosts accesibles

cat /etc/hosts
127.0.0.1	localhost
127.0.1.1	MateBook

# The following lines are desirable for IPv6 capable hosts
::1     ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters

192.168.56.100	apihub
192.168.56.101	app1
192.168.56.102	app2
192.168.56.110	central1

Autentificación SSH Key

Genera clave privada/publica en cliente

ssh-keygen -t rsa -b 4096

Sube la clave publica al servidor

modo facil

$ ssh-copy-id janrax@servidor 

modo dificil

# desde cliente
$ scp /home/janrax/.ssh/id_rsa.pub janrax@server:/home/janrax/.ssh/uploaded_key.pub
# en servidor
$ cat /home/janrax/.ssh/uploaded_key.pub >> /home/janrax/.ssh/authorized_keys
$ chmod 700 /home/janrax/.ssh
$ chmod 600 /home/janrax/.ssh/*

Que ssh solo permita conexión con clave publica/privada

$ cat vi /etc/ssh/sshd_config 
...
PasswordAuthentication no
...

$ sudo service ssh restart

Docker para colegas

Instalación

sudo apt-get install docker.io docker-compose docker-buildx

sudo groupadd docker
sudo usermod -aG docker $USER

sudo reboot

Kubernetes

Instalar cluster local ( minikube )

https://minikube.sigs.k8s.io/docs/start/

Recuerda poner esto .bashrc

alias kubectl="minikube kubectl --"

Comandos cluster

minikube start
minikube dashboard --url
minikube stop
minikube status

comandos kubectl

kubectl run miapp --image=jrgavilanes/mi_nginx --port 8080

kubectl get pods

kubectl describe pod miapp

kubectl expose pod miapp --type=LoadBalancer --port=8080 --target-port=80

kubectl get services

kubectl describe service miapp

minikube service --url miapp ( me devuelve la url exterior )

sobre secrets

janrax@janrax-matebook:~/Escritorio/Code/mi-kubernetes$ echo -n "clave_codificada" | base64
Y2xhdmVfY29kaWZpY2FkYQ==
janrax@janrax-matebook:~/Escritorio/Code/mi-kubernetes$ echo 'Y2xhdmVfY29kaWZpY2FkYQ==' | base64 --decode
clave_codificada

Comandos Básicos Docker

docker run debian ping google.es

docker run -it debian /bin/bash

docker images

docker ps -a

docker create debian # devuelve container_id

docker start <container_id>
docker logs <container_id>
docker stop <container_id>
docker kill <container_id>

docker start -a <container_id>

docker exec -it <container_id> /bin/bash

# Cuánto ocupa y borra datos
docker system df -v
docker system prune -a

# Borrar volumes
docker volume prune

Dockerfile

FROM debian
RUN apt update
CMD ["ping", "google.es"]
docker build -f Dockerfile .    # Si no pones -f va por defecto a Dockerfile
docker build -t jrgavilanes/proyecto:version .

Imagen desde contenedor ( No recomendado)

docker commit -c 'CMD ["ping", "google.es"]' <container_id>

Redireccionando puerto

docker run -p 5000:8080 <imagen_id>

Ejemplo de guay:

# Dockerfile
FROM debian
RUN apt update
RUN apt install -y python3 python3-pip
WORKDIR /app
CMD ["python3", "-m", "http.server"]

Rúlalo

docker -t imagen_juanra build .
docker run --name contenedor_juanra -p 5000:8000 imagen_juanra

curl localhost:5000

Volumenes

docker run -it -v $(pwd):/app alpine sh

Apine

dockerfile alpine con ssh

# Dockerfile.apihub

FROM alpine
RUN apk update 
RUN apk add openssh
RUN ssh-keygen -A

RUN adduser --disabled-password --gecos "" juanra
RUN echo "juanra:juanra" | chpasswd

WORKDIR /app
COPY app.sh .

CMD ["sh", "app.sh"]

Docker-compose

docker-compose.yml

version: '3'

services: 
    apihub:
        build: 
            context: .
            dockerfile: Dockerfile.apihub
        
    
    app1:
        build: 
            context: .
            dockerfile: Dockerfile.apihub        
docker-compose up
docker-compose up --build
docker-compose down

EJEMPLO README apihub

Construye imagen

docker build -f Dockerfile.apihub -t jrgavilanes/apihub .

Construye contenedor

docker run -v $(pwd):/app --name apihub jrgavilanes/apihub
PING google.es (216.58.201.163): 56 data bytes
64 bytes from 216.58.201.163: seq=0 ttl=48 time=27.577 ms
64 bytes from 216.58.201.163: seq=1 ttl=48 time=65.366 ms
...

Arranca contenedor

docker start apihub
apihub

docker ps
CONTAINER ID        IMAGE                COMMAND             CREATED             STATUS              PORTS               NAMES
14b76d451e34        jrgavilanes/apihub   "ping google.es"    38 seconds ago      Up 8 seconds                            apihub

docker logs apihub 
PING google.es (216.58.201.163): 56 data bytes
64 bytes from 216.58.201.163: seq=0 ttl=48 time=27.577 ms
64 bytes from 216.58.201.163: seq=1 ttl=48 time=65.366 ms
64 bytes from 216.58.201.163: seq=2 ttl=48 time=248.764 ms
64 bytes from 216.58.201.163: seq=3 ttl=48 time=67.446 ms

Detén contenedor

docker stop apihub # En 10 segundos hace kill

docker kill apihub # Recomendado stop

Instalación automatizada

#!/bin/bash

# Habilitar modo estricto para manejar errores
set -e

echo "🚀 Iniciando instalación de entorno de desarrollo en LMDE..."

# 1️⃣ Actualizar el sistema
echo "🔄 Actualizando paquetes..."
sudo apt update && sudo apt upgrade -y

# 2️⃣ Instalar Apache
echo "🌐 Instalando Apache..."
sudo apt install -y apache2
sudo systemctl enable apache2
sudo systemctl start apache2

# 3️⃣ Instalar MySQL
echo "💾 Instalando MySQL Server..."
sudo apt install -y default-mysql-server
sudo systemctl enable mysql
sudo systemctl start mysql

# 4️⃣ Instalar PHP y extensiones necesarias
echo "🐘 Instalando PHP 8.2 y extensiones requeridas..."
sudo apt install -y php php-cli php-mbstring php-xml php-bcmath php-curl php-zip php-tokenizer php-common php-intl php-mysql php-gd libapache2-mod-php unzip curl htop vim

# Verificar instalación de PHP
php -v

# 5️⃣ Instalar Composer (gestor de dependencias PHP)
echo "📦 Instalando Composer..."
curl -sS https://getcomposer.org/installer | php
sudo mv composer.phar /usr/local/bin/composer
composer -V

# 6️⃣ Instalar Laravel Installer
echo "🌟 Instalando Laravel Installer..."
composer global require laravel/installer

# 7️⃣ Agregar Laravel al PATH
echo "🔧 Configurando Laravel Installer en el PATH..."
echo 'export PATH="$HOME/.config/composer/vendor/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc

# 8️⃣ Verificar instalación de Laravel
echo "🛠️ Verificando instalación de Laravel..."
laravel --version

# 9️⃣ Instalar Node.js y npm
echo "📦 Instalando Node.js y npm..."
sudo apt install -y nodejs npm
node -v
npm -v

# 🔟 Configurar permisos para Apache (Opcional, si usarás /var/www)
echo "🔧 Configurando permisos para Apache..."
sudo usermod -aG www-data $USER
sudo chown -R www-data:www-data /var/www
sudo chmod -R 775 /var/www

# Instalar Visual Studio Code
sudo apt update
sudo apt install -y wget gpg
wget -qO- https://packages.microsoft.com/keys/microsoft.asc | sudo tee /usr/share/keyrings/microsoft.asc
echo "deb [arch=amd64 signed-by=/usr/share/keyrings/microsoft.asc] https://packages.microsoft.com/repos/code stable main" | sudo tee /etc/apt/sources.list.d/vscode.list

sudo apt update
sudo apt install -y code

# Instalar DBeaver
wget https://dbeaver.io/files/dbeaver-ce_latest_amd64.deb && sudo dpkg -i dbeaver-ce_latest_amd64.deb && rm dbeaver-ce_latest_amd64.deb

# Instalar Docker
sudo apt-get install docker.io docker-compose -y && sudo usermod -aG docker $USER


# 1️⃣1️⃣ Reiniciar Apache para aplicar cambios
echo "🔄 Reiniciando Apache..."
sudo systemctl restart apache2

# 1️⃣2️⃣ Mensaje final
echo "✅ Instalación completa. Tu entorno está listo para programar con Laravel en LMDE."
echo "👉 Recuerda configurar MySQL con: sudo mysql_secure_installation"
echo "👉 Para crear un nuevo proyecto usa: laravel new miapp"
echo "👉 Para probar Laravel: php artisan serve"

exit 0



Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment