1 de marzo de 2025

Docker: comandos básicos

Gestión de Imágenes:

  • docker pull <nombre_de_la_imagen>[:<etiqueta>]:
    • Descarga una imagen desde un registro (como Docker Hub).
    • Ejemplo: docker pull ubuntu:latest
  • docker images:
    • Lista todas las imágenes de Docker almacenadas localmente.
  • docker rmi <ID_de_la_imagen>:
    • Elimina una imagen de Docker.
    • Precaución: esta acción no se puede deshacer.

Gestión de Contenedores:

  • docker run [opciones] <nombre_de_la_imagen>[:<etiqueta>] [comando]:
    • Crea e inicia un contenedor a partir de una imagen.
    • Opciones clave:
      • docker run -d: Ejecuta el contenedor en modo "detached" (en segundo plano).
      • docker run -p <puerto_del_host>:<puerto_del_contenedor>: Asigna puertos entre el host y el contenedor.
      • docker run -v <ruta_del_host>:<ruta_del_contenedor>: Monta un volumen.
      • docker run --name <nombre_del_contenedor>: Asigna un nombre al contenedor.
    • Ejemplo: docker run -d -p 8080:80 nginx
  • docker ps:
    • Lista los contenedores en ejecución.
    • docker ps -a: lista todos los contenedores.
  • docker stop <ID_del_contenedor> o <nombre_del_contenedor>:
    • Detiene un contenedor en ejecución.
  • docker start <ID_del_contenedor> o <nombre_del_contenedor>:
    • Inicia un contenedor detenido.
  • docker restart <ID_del_contenedor> o <nombre_del_contenedor>:
    • reinicia un contenedor.
  • docker rm <ID_del_contenedor> o <nombre_del_contenedor>:
    • Elimina un contenedor detenido.
  • docker exec -it <ID_del_contenedor> o <nombre_del_contenedor> [comando]:
    • Ejecuta un comando dentro de un contenedor en ejecución.
    • -it proporciona una terminal interactiva.
    • Ejemplo: docker exec -it mi_contenedor bash
  • docker logs <ID_del_contenedor> o <nombre_del_contenedor>:
    • Muestra los registros de un contenedor.

Otros Comandos Útiles:

  • docker search <término>:
    • Busca imágenes en Docker Hub.
  • docker version:
    • Muestra la información de la versión de Docker.
  • docker info:
    • Muestra información general sobre la instalación de docker.

Conceptos Clave:

  • Imágenes: Plantillas de solo lectura utilizadas para crear contenedores.
  • Contenedores: Instancias en ejecución de imágenes.
  • Docker Hub: Un registro público de imágenes de Docker.

Con estos comandos básicos, podrás empezar a utilizar Docker de manera efectiva.

Instalar WireGuard con Docker en Raspberry Pi

  1.  Instalar Docker en tu máquina:

    • Si utilizas un sistema operativo basado en Linux, puedes utilizar el siguiente comando en la terminal:
    curl -sSL https://get.docker.com | sh
    
  2. Añadir tu usuario actual al grupo "docker":

    • Esto te permitirá detener e iniciar el contenedor Docker de WireGuard sin necesidad de utilizar el superusuario.
    sudo usermod -aG docker $USER
    
  3. Cerrar sesión y volver a iniciarla o reiniciar tu máquina:

    • Los cambios en los usuarios de Linux requieren que cierres sesión y vuelvas a iniciarla. Si utilizas SSH para conectarte a tu máquina, puedes cerrar sesión fácilmente con el siguiente comando:
    logout
    
    • Alternativamente, puedes reiniciar tu máquina ejecutando el siguiente comando:
    sudo reboot
    
  4. Preparar WireGuard:

    • Debes tener tu dispositivo accesible desde fuera de tu red. Esto significa que debes reenviar el puerto en una red doméstica y asegurarte de que tu dispositivo tenga una dirección IP estática. Para acceder a tu VPN de WireGuard desde fuera de tu red, debes abrir el puerto "51820". Si necesitas especificar el protocolo, utiliza "UDP".
  5. Crear un directorio para almacenar el archivo Compose:

    • También es la misma ubicación donde almacenaremos todos los archivos de configuración de Wireguard. Puedes crear un directorio en "/opt/stacks/wireguard" utilizando el comando mkdir.
    sudo mkdir -p /opt/stacks/wireguard
    
    • Al utilizar la opción "-p", nos aseguramos de que este comando cree toda la ruta, en lugar de simplemente intentar crear la ruta final.
  6. Cambiar al directorio:

    cd /opt/stacks/wireguard
    
  7. Generar un hash de contraseña:

    • Antes de configurar el archivo Compose para WireGuard, necesitaremos generar un hash rápido para la contraseña que pretendes utilizar. Afortunadamente, el contenedor Docker tiene un script fácil que podemos ejecutar. Dentro de la terminal, ejecuta el siguiente comando. Al escribir este comando, asegúrate de reemplazar "<PASSWORD>" con la contraseña que pretendes utilizar para acceder a la interfaz web de WG-Easy.
     docker run --rm -it ghcr.io/wg-easy/wg-easy wgpw '<PASSWORD>'
    
    • Por ejemplo, para generar un hash para la contraseña "pimylifeup", ejecutaríamos el siguiente comando.
    docker run --rm -it ghcr.io/wg-easy/wg-easy wgpw 'pimylifeup'
    
  8. Modificar el hash de la contraseña:

    • Antes de utilizar esta línea en el archivo Docker Compose, requiere algunas modificaciones.
    PASSWORD_HASH='$2b$12$coPqCsPtcFO.Ab99xylBNOW4.Iu7OOA2/ZIboHN6/oyxca3MWo7fW'
    
    • Antes de escribir este valor de hash de contraseña, elimina las dos comillas simples (') y añade un signo de dólar ($) adicional después de cada signo de dólar. Por ejemplo, nuestra línea anterior se convertiría en la siguiente
    PASSWORD_HASH=$$2b$$12$$coPqCsPtcFO.Ab99xylBNOW4.Iu7OOA2/ZIboHN6/oyxca3MWo7fW
    
  9. Escribir un archivo Docker Compose para Wireguard:

    • Ejecuta el siguiente comando para comenzar a escribir este archivo utilizando el editor de texto nano.
    sudo nano compose.yaml
    
    • Dentro de este archivo, querrás escribir las siguientes líneas.
    <PASSWORD_HASH> : Reemplaza este marcador de posición con el valor que obtuviste anteriormente en esta guía. La contraseña que se generó para este hash es la que utilizarás para iniciar sesión en la interfaz web de WG-Easy. Esta interfaz web es la que utilizarás para crear y gestionar clientes para tu VPN de WireGuard fácilmente.
    
    Esta línea terminará pareciéndose un poco a lo que hemos mostrado a continuación. El hash debería diferir ya que tu contraseña y "sal" serán diferentes.
    
    - PASSWORD_HASH=$$2b$$12$$coPqCsPtcFO.Ab99xylBNOW4.Iu7OOA2/ZIboHN6/oyxca3MWo7fW
    
    <IPADDRESS> : A continuación, especifica la dirección IP o el nombre de dominio donde se puede acceder a tu VPN. La dirección IP debe ser tu dirección IP externa y no local. Además, si utilizas un nombre de dominio, querrás asegurarte de que esté apuntando a donde está alojada tu VPN de WireGuard.
    services:
      wg-easy:
        container_name: wg-easy
        image: ghcr.io/wg-easy/wg-easy
        environment:
          - <PASSWORD_HASH>
          - WG_HOST=<IPADDRESS>
        volumes:
          - ./config:/etc/wireguard
          - /lib/modules:/lib/modules
        ports:
          - "51820:51820/udp"
          - "51821:51821/tcp"
        restart: unless-stopped
        cap_add:
          - NET_ADMIN
          - SYS_MODULE
        sysctls:
          - net.ipv4.ip_forward=1
          - net.ipv4.conf.all.src_valid_mark=1
    
  10. Guardar y salir del archivo:

    • Después de escribir las líneas anteriores, puedes guardar y salir presionando CTRL + X, Y y, finalmente, la tecla ENTER.
  11. Iniciar el stack de Docker de Wireguard:

    • Con el archivo Compose escrito, iniciar WireGuard utilizando Docker es increíblemente sencillo. Para poner en marcha nuestra VPN, necesitamos utilizar el siguiente comando.
    docker compose up -d
    
    • Al utilizar la opción "-d", le estamos diciendo a Docker que se desconecte de la terminal una vez que haya iniciado nuestro contenedor WireGuard.
  12. Acceder a la interfaz web del contenedor Docker de Wireguard:

    • Antes de que puedas empezar a utilizar tu nueva VPN, necesitarás crear un nuevo cliente. Normalmente, esto puede ser un poco complicado, pero el contenedor que estamos utilizando viene con una interfaz web súper fácil de usar. Para acceder a esta interfaz web, necesitarás conocer la dirección IP local de tu dispositivo. Puedes obtener esta IP fácilmente utilizando el comando hostname.
    hostname -I
    
  13. Ir a la siguiente dirección para acceder a la interfaz web de WG-Easy:

    http://<IPADDRESS>:51821
    
  14. Utilizar WG-Easy para gestionar tu contenedor Docker de Wireguard:

    • Ahora deberías ver la siguiente pantalla pidiéndote que inicies sesión en la interfaz web de WG-Easy. Primero, debes escribir la contraseña que estableciste anteriormente en esta guía (1.). Después de escribir tu contraseña, simplemente haz clic en el botón "Sign In" (2.) para acceder a la interfaz web.
  15. Crear tu primer cliente:

    • Una vez que hayas iniciado sesión, puedes crear tu primer cliente para tu contenedor Docker de VPN de WireGuard. Para comenzar este proceso, haz clic en el botón "+ NEW" o "+ New Client".
  16. Nombrar tu nuevo cliente:

    • En esta pantalla, ahora querrás dar un nombre a tu nuevo cliente (1.). Nombra esto algo para que sepas dónde se está utilizando este cliente. Después de escribir un nombre, haz clic en el botón "Create" (2.).
  17. Descargar los detalles de tu cliente:

    • En este punto, finalmente tienes WireGuard en funcionamiento utilizando un contenedor Docker. Ahora puedes descargar los detalles de tu cliente y conectarte a tu VPN. La interfaz web de WG-Easy que estamos utilizando te permite generar un código QR (2.) para añadir fácilmente tu cliente. También puedes descargar los archivos de configuración si tu cliente no admite el escaneo de códigos QR (3.). Si quieres evitar que un cliente acceda a tu VPN de WireGuard, puedes hacer clic en el interruptor (1.).

Siguiendo estos pasos, deberías poder instalar y configurar WireGuard en tu Raspberry Pi utilizando Docker.

Ref:
https://pimylifeup.com/wireguard-docker/
https://gemini.google.com

23 de febrero de 2025

Protocol for Setting Up OpenVPN on Raspberry Pi Using PiVPN

This guide will walk you through installing and configuring OpenVPN on a Raspberry Pi using PiVPN.


1. Prerequisites

  • Raspberry Pi (Raspberry Pi 3, 4, or 5 recommended)
  • Raspberry Pi OS (Lite or Full version)
  • Internet connection
  • SSH access or direct terminal access
  • Static IP or Dynamic DNS (DDNS) for external access

2. Update and Upgrade System

Before installing OpenVPN, update the system:

sudo apt update && sudo apt upgrade -y

3. Install PiVPN

Run the PiVPN installation script:

curl -L https://install.pivpn.io | bash

This launches an interactive installer.


4. Configure OpenVPN

During installation, follow these steps:

  1. Select OpenVPN when prompted.

  2. Set Static IP Address
    • The installer will ask if you want to set a static IP.
    • Accept the default or manually configure one.

  3. Select UDP or TCP
    • UDP (default, recommended) for better performance.
    • TCP for firewall bypassing but slower speed.

  4. Choose Port (Default: 1194)
    • You can change it if needed.

  5. Choose Encryption Settings
    • Select RSA key size (default: 2048-bit or 4096-bit for stronger security).

  6. Select DNS Provider
    • Choose from OpenDNS, Google, Cloudflare, or a custom DNS.

  7. Confirm Installation
    • The script will install and configure OpenVPN.

5. Create a VPN User Profile

After installation, create a VPN user profile:

pivpn add

Follow the prompts to:

  • Enter a username.
  • Set a password (if required).

This will generate a .ovpn configuration file stored in /home/pi/configs/.


6. Configure Port Forwarding

To access the VPN from outside your network:

  1. Log in to your router’s admin panel.
  2. Locate Port Forwarding settings.
  3. Forward UDP Port 1194 to your Raspberry Pi’s local IP address.
  4. Save and restart your router.

7. Transfer the VPN Configuration File

To connect to your VPN, transfer the .ovpn file to your client device:

  • Use SCP, SFTP, or a USB drive to move the file.
  • Example command for SCP:
    scp pi@your_rpi_ip:/home/pi/configs/client.ovpn ~/Downloads/
    
  • Alternatively, use an SFTP client like WinSCP or FileZilla.

8. Connect to OpenVPN

  • PC (Windows/macOS/Linux):

    1. Install the OpenVPN client from openvpn.net.
    2. Import the .ovpn file.
    3. Click Connect.
  • Android/iOS:

    1. Install OpenVPN Connect from the App Store or Google Play.
    2. Import the .ovpn file.
    3. Connect to your VPN.

9. (Optional) Set Up Dynamic DNS (DDNS)

If your public IP changes frequently, use DDNS:

  • Sign up for a free No-IP or DuckDNS account.
  • Configure DDNS on your router or install a DDNS client on the Raspberry Pi.

Example (for No-IP):

sudo apt install ddclient
sudo nano /etc/ddclient.conf

Add your No-IP credentials and domain.


10. Test the VPN

  • Connect from an external network (e.g., mobile data).
  • Visit whatismyipaddress.com to check if your public IP matches your VPN server.

That's it! 🎉 Your OpenVPN server on Raspberry Pi is now set up.

Let me know if you need further assistance! 🚀

 

References:

ChatGPT. (2025, February 23). How to set up OpenVPN with a dynamic IP using DDNS on Raspberry Pi. OpenAI. Retrieved from https://chat.openai.com

ChatGPT. (2025, February 23). A conceptual digital illustration representing VPN, Linux, Raspberry Pi OS, Raspberry Pi, and travel [AI-generated image]. OpenAI.

 

4 de septiembre de 2024

Configurar HTTPS en apache2 con certificado autofirmado

Configurar Apache2 para usar HTTPS con un certificado autofirmado es un proceso relativamente sencillo. A continuación te guiaré paso a paso en cómo hacerlo en un sistema Linux, como Ubuntu o Debian.

### Paso 1: Instalar Apache2
Si no tienes Apache2 instalado, puedes hacerlo ejecutando el siguiente comando:

```bash
sudo apt update
sudo apt install apache2
```

### Paso 2: Habilitar el módulo SSL de Apache
Apache tiene un módulo para manejar conexiones SSL llamado `mod_ssl`. Para habilitarlo, ejecuta:

```bash
sudo a2enmod ssl
```

### Paso 3: Crear un certificado SSL autofirmado
Ahora vamos a crear un certificado autofirmado y una clave privada. Por defecto, el certificado SSL se genera para 365 días. Si deseas un período diferente, puedes cambiar el valor después de `-days`.

```bash
sudo mkdir /etc/apache2/ssl
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/apache2/ssl/apache-selfsigned.key -out /etc/apache2/ssl/apache-selfsigned.crt
```

Este comando hará lo siguiente:
- `-x509`: Indica que vamos a crear un certificado autofirmado.
- `-nodes`: No ciframos el archivo de clave privada.
- `-days 365`: El certificado será válido por 365 días.
- `-newkey rsa:2048`: Generamos una clave RSA de 2048 bits.
- `-keyout`: El archivo donde se almacenará la clave privada.
- `-out`: El archivo donde se almacenará el certificado.

Durante la generación del certificado, te pedirá información como el nombre del país, ciudad, organización, etc. Puedes completar estos campos o dejarlos en blanco.

### Paso 4: Configurar Apache para usar SSL
Ahora necesitamos configurar Apache para utilizar el certificado autofirmado. Vamos a modificar el archivo de configuración SSL predeterminado.

1. Abre el archivo de configuración de SSL para editarlo:

   ```bash
   sudo nano /etc/apache2/sites-available/default-ssl.conf
   ```

2. Busca las siguientes líneas y asegúrate de que apunten a los archivos de certificado y clave privada que acabas de crear:

   ```bash
   SSLCertificateFile /etc/apache2/ssl/apache-selfsigned.crt
   SSLCertificateKeyFile /etc/apache2/ssl/apache-selfsigned.key
   ```

3. Si deseas, puedes modificar otras configuraciones en este archivo para adaptarlas a tus necesidades, como el nombre del servidor (`ServerName`).

### Paso 5: Habilitar el sitio SSL
Con el archivo configurado, habilitamos el sitio SSL predeterminado con el siguiente comando:

```bash
sudo a2ensite default-ssl.conf
```

### Paso 6: Reiniciar Apache
Para aplicar los cambios, reinicia Apache:

```bash
sudo systemctl restart apache2
```

### Paso 7: Prueba la configuración
Ahora deberías poder acceder a tu servidor Apache a través de HTTPS. Abre un navegador y visita `https://<tu-dominio>` o `https://<tu-dirección-ip>`. Dado que estás utilizando un certificado autofirmado, el navegador mostrará una advertencia de seguridad. Puedes omitir esta advertencia para continuar.

### Opcional: Redirigir HTTP a HTTPS
Si deseas redirigir todo el tráfico HTTP a HTTPS, puedes añadir una redirección en el archivo de configuración de tu sitio principal. Abre el archivo de configuración de tu sitio en `/etc/apache2/sites-available/000-default.conf` y añade lo siguiente dentro del bloque `<VirtualHost *:80>`:

```apache
<VirtualHost *:80>
    ServerName tu-dominio.com
    Redirect / https://tu-dominio.com/
</VirtualHost>
```

Luego, reinicia Apache nuevamente:

```bash
sudo systemctl restart apache2
```

### Conclusión

Ahora has configurado Apache2 para usar HTTPS con un certificado SSL autofirmado. Aunque este tipo de certificados son útiles para pruebas y entornos de desarrollo, para producción es recomendable usar un certificado emitido por una Autoridad de Certificación (CA), como los proporcionados por Let's Encrypt.

Ref:

data from GPT-4 of OpenAI.
(I) Prompt: Como configurar apache2 con https usando certificado autofrmado.
(II) Image prompt: An illustration showing the process of configuring HTTPS on an Apache2 server using a self-signed certificate. The image should depict a server terminal with Apache2 logo, SSL keys being generated, and a certificate being configured. Include visual elements like a shield icon representing security (HTTPS), command-line code snippets, and a simplified server diagram with arrows indicating data flow over HTTPS. The overall tone should be technical yet approachable, with clear, organized elements representing each step in the setup process.

Image by Google Gemini 2025.

20 de mayo de 2023

Solventar Error de Firmas con aptitude update

Cuando aparace un error de verificación de firmas públicas al actualizar los paquetes linux-mint con aptitude, como el ejemplo:

#aptitude update
...
...
Err https://repo.protonvpn.com/debian unstable InRelease      
  Las firmas siguientes no se pudieron verificar porque su clave pública no está disponible: NO_PUBKEY YourKeyHere
...

Solución:

#apt-key adv --keyserver keyserver.ubuntu.com --recv-keys YourKeyHere

Executing: /tmp/apt-key-gpghome.czzxh7ycXx/gpg.1.sh --keyserver keyserver.ubuntu.com --recv-keys YourKeyHere
gpg: clave YourKeyHere: clave pública "Proton Technologies AG <opensource@proton.me>" importada
gpg: Cantidad total procesada: 1
gpg:               importadas: 1 

Ref:
https://chat.openai.com
http://misnotaslinux.blogspot.com/2011/03/error-de-gpg-nopubkey.html

 

21 de marzo de 2023

Montar una imagen de tarjeta SD de rpi en linux

1) Descomprimir el fichero SDrpi.img.gz manteniendo el original:

# gzip -dk SDrpi.img.gz

 

2) ver estructura del fichero imagen:

# fdisk -l SDrpi.img

Unidades: sectores de 1 * 512 = 512 bytes
Tamaño de sector (lógico/físico): 512 bytes / 512 bytes
Tamaño de E/S (mínimo/óptimo): 512 bytes / 512 bytes
Tipo de etiqueta de disco: dos
Identificador del disco: 0xb111a06d

Dispositivo Inicio Comienzo  Final Sectores Tamaño Id Tipo

SDrpi.img1            8192    93814    85623  41,8M  c W95 FAT32 (LBA)
SDrpi.img2           94208 62333951 62239744  29,7G 83 Linux 

 

3) Montar la partición 2 en /mnt/tmp:

Calcular valor del offset:

# echo "512 * 94208" | bc
48234496

# mount -o loop,offset=48234496 SDrpi.img /mnt/tmp

 

4) Comprobar:

$ cd /mnt/tmp

$ ll
total 104K
drwxr-xr-x   2 root root 4,0K sep 11  2019 bin
drwxr-xr-x   2 root root 4,0K sep  7  2017 boot
drwxr-xr-x   4 root root 4,0K sep  7  2017 dev
drwxr-xr-x 123 root root  12K nov  6  2019 etc
drwxr-xr-x   4 root root 4,0K ene  8  2019 home
drwxr-xr-x  16 root root 4,0K feb 20  2019 lib
drwx------   2 root root  16K sep  7  2017 lost+found
drwxr-xr-x   4 root root 4,0K sep 26  2017 media
drwxr-xr-x   3 root root 4,0K oct 24  2017 mnt
drwxr-xr-x   5 root root 4,0K feb  3  2019 opt
drwxr-xr-x   2 root root 4,0K jul 28  2017 proc
drwx------  24 root root 4,0K nov 22  2019 root
drwxr-xr-x   6 root root 4,0K sep  7  2017 run
drwxr-xr-x   2 root root  12K oct  2  2019 sbin
drwxr-xr-x   2 root root 4,0K sep  7  2017 srv
drwxr-xr-x   2 root root 4,0K jul 28  2017 sys
drwxrwxrwt   8 root root 4,0K nov 22  2019 tmp
drwxr-xr-x  11 root root 4,0K sep  7  2017 usr
drwxr-xr-x  12 root root 4,0K oct 14  2017 var

Ok, ya tenemos accesible el sistema de archivos de la images de la tarjeta SD de raspberry pi, disponible para consultar o tomar los que necesitemos.

 

5) desmontar al terminar:

# sudo umount /mnt/tmp




8 de marzo de 2023

Rpi test SD card speed with hdparm

 $ hdparm -tT /dev/mmcblk0 

------------------------------------------------------------ 

@rpi4:~ $ sudo hdparm -tT /dev/sdd  (16GB class 4 SD by USB reader)
/dev/sdd:
 Timing cached reads:   1404 MB in  2.00 seconds = 702.06 MB/sec
 Timing buffered disk reads:  58 MB in  3.05 seconds =  19.03 MB/sec

------------------------------------------------------------ 

@rpi4:~ $ sudo hdparm -tT /dev/mmcblk0 (128GB SD, class 10)
/dev/mmcblk0:
 Timing cached reads:   1470 MB in  2.00 seconds = 735.12 MB/sec
 Timing buffered disk reads: 128 MB in  3.02 seconds =  42.42 MB/sec

------------------------------------------------------------ 

@rpiap:~ $ sudo hdparm -tT /dev/mmcblk0 (16GB SD Class 10)
/dev/mmcblk0:
 Timing cached reads:   874 MB in  2.00 seconds = 437.44 MB/sec
 Timing buffered disk reads:  66 MB in  3.02 seconds =  21.86 MB/sec

------------------------------------------------------------

@rpi:~ $ sudo hdparm -tT /dev/mmcblk0 (32 GB SD class 10)
/dev/mmcblk0:
 Timing cached reads:   410 MB in  2.01 seconds = 204.42 MB/sec
 Timing buffered disk reads:  66 MB in  3.04 seconds =  21.70 MB/sec

------------------------------------------------------------ 

2 de marzo de 2023

Acivate event_scheduler in mariaDB

Protocol:


1) Edit mariadb config file:


# nano /etc/mysql/mariadb.conf.d/50-server.cnf

include the line: "event_sheduler = on"

2) Restart mariadb service:


# service mariadb restart

3) Check if allright:

$ service mariadb status 

 

Confirm that events are executed from now.

28 de febrero de 2023

How to Compile and Upload .ino file to Arduino board in Rpi Linux Shell


I have a system composed by RpiB+ and Arduino Uno board working together, monitoring parameters, triggering reles, storing data into MariaDB and presenting with apache2 webserver.

When I have to change arduino program I have to open vnc session, execute arduino-ide, edit sketch, compile and upload to arduino board !!, ... painful due limited resources o my old RpiB+.

Thus, can I compile and upload and .ino file from rpi linux shell ??

Yes, and very ease.

 

Protocol:

Install arduino, if not installed already:

# aptitude install arduino

Compile and upload Shell command:

$ arduino --upload yourfile.ino --port yourArduinoport

 

Example:

$ arduino --upload example.ino --port /dev/ttyACM0

Picked up JAVA_TOOL_OPTIONS:
Cargando configuración...
Inicializando paquetes...
Preparando tarjetas...
Verficando...
...
El Sketch usa 16464 bytes (51%) del espacio de almacenamiento de programa. El máximo es 32256 bytes.
Las variables Globales usan 754 bytes (36%) de la memoria dinámica, dejando 1294 bytes para las variables locales. El máximo es 2048 bytes.
Subiendo...
...

I can also modify the .ino sketches with nano, compile and upload them to arduino from shell, without need any graphical environment.

Ref.:
https://arduino.stackexchange.com/questions/15893/how-to-compile-upload-and-monitor-via-the-linux-command-line