Nicotine+ as a Web UI in a Docker container
100K+
Nicotine+ is a graphical client for the Soulseek peer-to-peer network.
Nicotine+ aims to be a lightweight, pleasant, free and open source (FOSS) alternative to the official Soulseek client, while also providing a comprehensive set of features.
For more information, head to the official Nicotine+ website
This is a Nicotine+ Docker image, using port 6565 (by default) to access Nicotine+ in a browser using the Broadway back end of GTK as the display server. This makes the image extremely small, lightweight, and fast, because it has less complications and dependencies. This also means there is no authentication available to access the application (as there would be with noVNC). If you plan to use this remotely as part of your self-hosted setup, you'll need to use something like Authentik or Authelia to provide the authenticaion layer. Alternatively, you could use a self-hosted VPN server and access the application externally as if you're on the local network. These items are outside the scope of this project but I wanted to provide alternatives if you need to access the application while you're away from your local network.
Because the application renders natively in a browser when using the Broadway back end of GTK, certain features and UI elements are not needed (e.g. window control buttons). The Nicotine+ developers were kind enough to create an isolated mode for this project. This creates a more native browser-based experience by removing links and references to external applications and websites, among other things. All of my images now run in isolated mode.
This image is inspired by 33masterman33's clone of freddywullockx's Nicotine+ Docker image. Since the original release that was built on top of the aforementioned images, I've rebuilt the image from scratch, with expanded features and complexity. This is now a completely unique project, but loads of credit should still be given to freddywullockx and 33masterman33 for the inspiration and concept.
You can also find this project on GitHub
---
services:
nicotineplus-proper:
image: 'sirjmann92/nicotineplus-proper:latest' # Or pull from GitHub: 'ghcr.io/sirjmann92/nicotineplus-proper:latest'
container_name: nicotine
# network_mode: "container:YourVPNContainerNameHere" # Comment this line out if you're NOT using a VPN container
ports: # Comment this line out if you ARE using a VPN container (line above)
- '6565:6565' # Comment this line out if you ARE using a VPN container (lines above)
- '2234:2234' # Comment this line out if you ARE using a VPN container (lines above)
# env_file: .env # Optionally use a .env file to store environment variables and login credentials
environment: # All environment variables are optional, defaults are listed (TZ, LANG, UMASK, and FORWARD_PORT have no default)
- TZ=Your/Timezone
- LOGIN=YourSoulSeekUsername
- PASSW=YourSoulSeekPassword
# - PUID=1000
# - PGID=1000
# - DARKMODE=True
# - LANG=C.UTF-8
# - UMASK=022
# - UPNP=False
# - AUTO_CONNECT=True
# - TRAY_ICON=False
# - NOTIFY_FILE=False
# - NOTIFY_FOLDER=False
# - NOTIFY_TITLE=False
# - NOTIFY_PM=False
# - NOTIFY_CHATROOM=False
# - NOTIFY_MENTION=False
# - FORWARD_PORT=12345 # Useful for dynamic port forwarding
# - WEB_UI_PORT=6565 # for custom webUI port assignment. Should match 'port' env variable or VPN webUI port
# - WEB_UI_USER=YourWebUIUsername # for custom webUI basic auth username
# - WEB_UI_PASSWORD=YourWebUIPassword # for custom webUI basic auth password
volumes:
- /your/downloads/directory:/downloads
- /your/share/directory:/shared
- /your/local/directory/config:/config # Save your config persistently
- /your/local/directory/config/data:/data # Store your logs, database, and history
restart: unless-stopped
docker run -d --name=nicotine \
//--net=container:YourVPNClientContainerName \
--restart=unless-stopped \
-v /your/media/directory:/downloads \
-v /your/share/directory:/shared \
-v /your/local/directory/config:/config \
-v /your/local/directory/config/data:/data \
-e TZ=Your/Timezone \
-e LOGIN=YourSoulSeekUsername \
-e PASSW=YourSoulSeekPassword \
-e PUID=1000 \
-e PGID=1000 \
//-e DARKMODE=True \
//-e LANG=C.UTF-8 \
//-e UMASK=022 \
//-e FORWARD_PORT=12345 \
//-e WEB_UI_PORT=6565 \
//-e WEB_UI_USER=YourWebUIUsername \
//-e WEB_UI_PASSWORD=YourWebUIPassword \
-p 6565:6565 \
-p 2234:2234 \
sirjmann92/nicotineplus-proper:latest
// or pull from GitHub: ghcr.io/sirjmann92/nicotineplus-proper:latest
You can access your Nicotine+ WebUI with http://your.server.ip.here:6565 (e.g. http://192.168.1.555:6565)
The container is pre-configured to handle WebSocket connections properly when accessed directly. However, if you're using a reverse proxy (Nginx Proxy Manager, Traefik, Caddy, etc.) in front of this container, you must configure your reverse proxy to handle WebSocket connections, otherwise the Broadway interface will disconnect after a few minutes.
This is a limitation of how WebSockets work through multiple proxy layers - each proxy in the chain must be configured to maintain the WebSocket connection. The container's internal nginx is already configured correctly, but your external reverse proxy needs WebSocket support enabled as well.
Broadway (the GTK display backend) uses WebSockets to maintain a live connection between your browser and the application. When you access the container directly, everything works seamlessly. However, when you add a reverse proxy:
Nginx Proxy Manager / Nginx - Add to "Advanced" tab or custom location:
location /socket {
proxy_pass http://container-ip:6565/socket;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_read_timeout 86400;
proxy_send_timeout 86400;
proxy_buffering off;
proxy_request_buffering off;
proxy_cache_bypass $http_upgrade;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
Traefik - Add these labels to your docker-compose:
labels:
- "traefik.http.routers.nicotine.middlewares=nicotine-headers"
- "traefik.http.middlewares.nicotine-headers.headers.customrequestheaders.Connection=upgrade"
- "traefik.http.middlewares.nicotine-headers.headers.customrequestheaders.Upgrade=websocket"
Caddy - Add to your Caddyfile:
your.domain.com {
reverse_proxy /socket* container-ip:6565 {
flush_interval -1
}
reverse_proxy container-ip:6565
}
If you're using an authentication proxy like Authentik or Authelia, the WebSocket configuration must be applied to the reverse proxy that sits in front of the authentication layer, not within the authentication proxy itself.
When a new version of Nicotine+ is released, you have two options of upgrading
Make sure your nicotine container is RUNNING when you do this
With a user that has Docker permissions (or sudo), SSH into your NAS/server or open your CLI terminal
To connect to your container's shell (command line), copy and paste this into your terminal
sudo docker exec -it nicotine bash
If you want to update all packages inside the container, copy and paste this into your container's shell:
apt update &&
apt -y upgrade &&
apt -y autoremove
If you only want to update Nicotine+ inside the container, copy and paste this instead:
apt update &&
apt -y upgrade nicotine &&
apt -y autoremove
Restart the container when finished. The apt autoremove command will check for any unnecessary packages and dependencies and remove any it finds, useful for controlling image size.
To list all packages contained in image (with version and description):
docker exec -i <container_id> dpkg -l
If you're interested in making modifications, or simply prefer to build your own image from the project files, you may download or clone the project and run the following from within the project directory:
docker build -t yourImageName .
Content type
Image
Digest
sha256:8e8dd77c6…
Size
223.1 MB
Last updated
6 days ago
docker pull sirjmann92/nicotineplus-proper