Initial commit: Nicotine-Less Docker container

Lightweight Docker container for Nicotine+ with noVNC web interface and Firefox ESR browser.

Features:
- noVNC web interface with dynamic resize support
- Firefox ESR for testing ports and browsing
- TigerVNC with AcceptSetDesktopSize enabled
- Supervisor for process management
- Configurable user/group permissions

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-10-19 20:09:10 +02:00
commit b0c6d76797
9 changed files with 405 additions and 0 deletions

6
.gitignore vendored Normal file
View File

@@ -0,0 +1,6 @@
# Dati utente e configurazioni personali
data/
# File di configurazione personalizzati
nicotine-config
docker-compose.yml

89
Dockerfile Normal file
View File

@@ -0,0 +1,89 @@
FROM debian:bookworm-slim
# Metadata
LABEL maintainer="Nicola"
LABEL description="Nicotine+ with noVNC web interface and SSH X forwarding support"
LABEL version="1.0"
# Evita prompt interattivi
ENV DEBIAN_FRONTEND=noninteractive
# Variabili d'ambiente
ENV DISPLAY=:0 \
VNC_PORT=5900 \
NOVNC_PORT=6080 \
VNC_RESOLUTION=1280x720 \
VNC_DEPTH=24 \
USER=nicotine \
PUID=1000 \
PGID=1000
# Installa dipendenze
RUN apt-get update && apt-get install -y \
# Window manager leggero
openbox \
xterm \
dbus-x11 \
# VNC server (solo per noVNC backend)
tigervnc-standalone-server \
tigervnc-common \
# noVNC per interfaccia web
novnc \
python3-websockify \
# Dipendenze Nicotine+
python3 \
python3-pip \
python3-gi \
python3-gi-cairo \
gir1.2-gtk-3.0 \
# Browser leggero
firefox-esr \
# Per SSH X forwarding
xauth \
# Supervisord per gestire i processi
supervisor \
# Utility
wget \
curl \
procps \
net-tools \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
# Installa Nicotine+ ultima versione
RUN pip3 install --no-cache-dir --break-system-packages nicotine-plus
# Crea utente non-root
RUN groupadd -g ${PGID} ${USER} && \
useradd -u ${PUID} -g ${PGID} -m -s /bin/bash ${USER}
# Crea directory
RUN mkdir -p \
/config \
/downloads \
/incomplete \
/home/${USER}/.config/openbox \
/home/${USER}/.config/nicotine \
/home/${USER}/.vnc \
/var/log/supervisor
# Copia configurazioni
COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf
COPY entrypoint.sh /usr/local/bin/entrypoint.sh
COPY openbox-rc.xml /home/${USER}/.config/openbox/rc.xml
COPY index.html /usr/share/novnc/index.html
# Permessi
RUN chmod +x /usr/local/bin/entrypoint.sh \
&& chown -R ${USER}:${USER} /home/${USER} /config /downloads /incomplete
# Esponi solo noVNC e porte Soulseek
EXPOSE 6080 2234 2235/udp
# Volumi
VOLUME ["/config", "/downloads", "/incomplete"]
WORKDIR /home/${USER}
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf"]

97
README.md Normal file
View File

@@ -0,0 +1,97 @@
# Nicotine-Less
Lightweight Docker container for Nicotine+ (Soulseek client) with noVNC web interface and integrated Firefox ESR browser.
## Features
- Web interface accessible from browser (noVNC)
- Integrated Firefox ESR browser
- Dynamic VNC window resizing
- SSH X forwarding support
- Persistent volumes for configuration and downloads
## Requirements
- Docker and Docker Compose installed
- Available ports: 6080 (web), 2234 (TCP), 2235 (UDP)
## Installation
### 1. Clone the repository
```bash
git clone https://git.nicola.sh/public/nicotine-less.git
cd nicotine-less
```
### 2. Configure docker-compose.yml
Copy the example file and edit it:
```bash
cp docker-compose.yml.example docker-compose.yml
```
**Required changes in `docker-compose.yml`:**
- Set your download and incomplete paths:
```yaml
volumes:
- ./data/config:/config
- /path/to/your/downloads:/downloads # CHANGE THIS
- /path/to/your/incomplete:/incomplete # CHANGE THIS
```
- (Optional) Add shared folders:
```yaml
- /path/to/your/music:/shares/music:ro # ADD YOUR SHARES
```
- (Optional) Adjust PUID/PGID to match your user:
```bash
id -u # Get your user ID
id -g # Get your group ID
```
### 3. Create config directory
```bash
mkdir -p data/config
```
### 4. Build and start
```bash
docker compose build
docker compose up -d
```
## Usage
### Web access
Open browser:
```
http://localhost:6080
```
Or from another device:
```
http://YOUR_HOST_IP:6080
```
### SSH X Forwarding
```bash
ssh -X user@host_ip
docker exec -it nicotine-less nicotine
```
## License
This project is provided "as-is" without warranties.
## Links
- [Nicotine+ GitHub](https://github.com/nicotine-plus/nicotine-plus)
- [noVNC GitHub](https://github.com/novnc/noVNC)

View File

@@ -0,0 +1,60 @@
services:
nicotine-less:
build: .
container_name: nicotine-less
image: nicotine-less:latest
restart: unless-stopped
# Porte
ports:
- "6080:6080" # Interfaccia web noVNC
- "2234:2234" # Porta Soulseek TCP
- "2235:2235/udp" # Porta Soulseek UDP
# Variabili d'ambiente
environment:
- PUID=1000 # User ID (cambia se necessario)
- PGID=1000 # Group ID (cambia se necessario)
- TZ=Europe/Rome # Timezone
- VNC_RESOLUTION=1920x1080 # Risoluzione desktop
- VNC_DEPTH=24 # Profondità colore
- VNC_PASSWORD=nicotine # Password per VNC (opzionale)
- DISPLAY=:0
# Volumi persistenti
volumes:
# Configurazione Nicotine+ (database, settings, liste utenti, ecc)
- ./data/config:/config
# Download completati - MODIFICA CON IL TUO PERCORSO
- /path/to/your/downloads:/downloads
# Download incompleti/in corso - MODIFICA CON IL TUO PERCORSO
- /path/to/your/incomplete:/incomplete
# Opzionale: cartelle condivise aggiuntive - MODIFICA CON I TUOI PERCORSI
# - /path/to/your/music:/shares/music:ro
# - /path/to/your/other:/shares/other:ro
# Limiti risorse (opzionale, utile per Raspberry Pi)
deploy:
resources:
limits:
memory: 1G
cpus: '2'
reservations:
memory: 256M
# Network
network_mode: bridge
# Privileged mode non necessario
privileged: false
# Healthcheck
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:6080"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s

43
entrypoint.sh Executable file
View File

@@ -0,0 +1,43 @@
#!/bin/bash
set -e
# Aggiorna PUID e PGID se necessario
if [ ! -z "$PUID" ] && [ "$PUID" != "1000" ]; then
usermod -u $PUID nicotine
fi
if [ ! -z "$PGID" ] && [ "$PGID" != "1000" ]; then
groupmod -g $PGID nicotine
fi
# Correggi permessi sui volumi
chown -R nicotine:nicotine /config /downloads /incomplete 2>/dev/null || true
# Crea directory necessarie
mkdir -p /home/nicotine/.local/share/nicotine
chown -R nicotine:nicotine /home/nicotine/.local
# Crea link simbolico dalla config di Nicotine+ al volume persistente
if [ ! -L "/home/nicotine/.config/nicotine" ]; then
rm -rf /home/nicotine/.config/nicotine
ln -s /config /home/nicotine/.config/nicotine
fi
# Configura password VNC se specificata
if [ ! -z "$VNC_PASSWORD" ]; then
mkdir -p /home/nicotine/.vnc
echo "$VNC_PASSWORD" | vncpasswd -f > /home/nicotine/.vnc/passwd
chmod 600 /home/nicotine/.vnc/passwd
chown nicotine:nicotine /home/nicotine/.vnc/passwd
fi
# Esporta variabili d'ambiente per supervisord
export DISPLAY
export VNC_PORT
export NOVNC_PORT
export VNC_RESOLUTION
export VNC_DEPTH
export USER
# Avvia supervisord come root (che poi farà partire i processi come utente nicotine)
exec "$@"

12
index.html Normal file
View File

@@ -0,0 +1,12 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="refresh" content="0; url=vnc.html?autoconnect=true&resize=remote&reconnect=true">
<title>Nicotine+ noVNC</title>
</head>
<body>
<p>Redirecting to noVNC with remote resize enabled...</p>
<p>If not redirected automatically, <a href="vnc.html?autoconnect=true&resize=local">click here</a>.</p>
</body>
</html>

5
openbox-autostart.sh Executable file
View File

@@ -0,0 +1,5 @@
#!/bin/bash
# Avvia Nicotine+ automaticamente
sleep 2
nicotine &

50
openbox-rc.xml Normal file
View File

@@ -0,0 +1,50 @@
<?xml version="1.0" encoding="UTF-8"?>
<openbox_config xmlns="http://openbox.org/3.4/rc"
xmlns:xi="http://www.w3.org/2001/XInclude">
<desktops>
<!-- This wm is GNOME aware -->
<number>1</number>
<!-- Always try to focus new windows when they appear. other rules do
apply -->
<firstdesk>1</firstdesk>
<names>
<name>Desktop</name>
</names>
<popupTime>0</popupTime>
</desktops>
<mouse>
<dragThreshold>8</dragThreshold>
<doubleClickTime>500</doubleClickTime>
<screenEdgeWarpTime>0</screenEdgeWarpTime>
<screenEdgeWarpMouse>false</screenEdgeWarpMouse>
<context name="Desktop">
<mousebind button="Up" action="Click">
<!-- Disabled desktop switching with mouse wheel -->
</mousebind>
<mousebind button="Down" action="Click">
<!-- Disabled desktop switching with mouse wheel -->
</mousebind>
</context>
<context name="Titlebar">
<mousebind button="Left" action="Drag">
<action name="Move"/>
</mousebind>
<mousebind button="Left" action="DoubleClick">
<action name="ToggleMaximize"/>
</mousebind>
<mousebind button="Up" action="Click">
<!-- Disabled desktop switching -->
</mousebind>
<mousebind button="Down" action="Click">
<!-- Disabled desktop switching -->
</mousebind>
</context>
</mouse>
<keyboard>
<chainQuitKey>C-g</chainQuitKey>
</keyboard>
</openbox_config>

43
supervisord.conf Normal file
View File

@@ -0,0 +1,43 @@
[supervisord]
nodaemon=true
user=root
logfile=/var/log/supervisor/supervisord.log
pidfile=/var/run/supervisord.pid
[program:xvnc]
command=/usr/bin/Xvnc :0 -geometry %(ENV_VNC_RESOLUTION)s -depth %(ENV_VNC_DEPTH)s -SecurityTypes None -rfbport %(ENV_VNC_PORT)s -AcceptSetDesktopSize=1
user=%(ENV_USER)s
autostart=true
autorestart=true
priority=10
stdout_logfile=/var/log/supervisor/xvnc.log
stderr_logfile=/var/log/supervisor/xvnc_err.log
[program:openbox]
command=/usr/bin/openbox
environment=DISPLAY=":0"
user=%(ENV_USER)s
autostart=true
autorestart=true
priority=20
stdout_logfile=/var/log/supervisor/openbox.log
stderr_logfile=/var/log/supervisor/openbox_err.log
[program:novnc]
command=/usr/share/novnc/utils/novnc_proxy --vnc localhost:%(ENV_VNC_PORT)s --listen %(ENV_NOVNC_PORT)s
user=%(ENV_USER)s
autostart=true
autorestart=true
priority=30
stdout_logfile=/var/log/supervisor/novnc.log
stderr_logfile=/var/log/supervisor/novnc_err.log
[program:nicotine]
command=/usr/local/bin/nicotine
environment=DISPLAY=":0",HOME="/home/%(ENV_USER)s",XDG_CONFIG_HOME="/home/%(ENV_USER)s/.config",XDG_DATA_HOME="/home/%(ENV_USER)s/.local/share"
user=%(ENV_USER)s
autostart=true
autorestart=true
priority=40
stdout_logfile=/var/log/supervisor/nicotine.log
stderr_logfile=/var/log/supervisor/nicotine_err.log