Getting this HomeLAB enviornment working in your QNAP will probably require tweaking and troubleshooting.
Consider joining and contributing to the QNAP Unofficial Discord, a community built around advice on everything QNAP. We have helpful members, FAQs, community Docker images, and cookies (well, maybe not cookies).
I am quite active in the Discord, and will help when and if I can, but I can not be held responsible for issues created while following this guide or performing any suggestions I make.
WARNING: This guide is incomplete, and as such will probably contain errors.
Please read the disclaimer at the end of this document.
A desire to learn Docker and some basic Terminal commands.
A desktop with a Terminal application (e.g. Termius), and a text editor (e.g. VSCodium)
A QNAP device that supports the Container Station application and therefore Docker.
A Debian based Linux distribution with Docker installed via https://get.docker.com
Thanks for checking out this guide. If it ends up being useful for your setup, please consider donating!
QNAP HomeLAB Using Docker Containers
All actions in this section will be performed in the QNAP QTS Web UI.
If following this guide on a Debian based OS, QNAP specific steps are unnecessary.
QTS System UI
HTTP: 8480 | HTTPS: 8443
Web Server
HTTP: 9480 | HTTPS: 9443
SSH Terminal
example: 54545
-
For ease of configuration, ports 80, 443, and 8080 must be unused by your NAS.
- NOTE: This step may be unnecessary if you can get 'chained' port-forwards to work when configuring Traefik to recognize your domain and register a certificate. YMMV.
- EXPLANATION: QTS assigns ports 8080 and 443 as the default HTTP and HTTPS ports for the QNAP Web UI, and assigns 80 as the default HTTP port for the native "Web Server" application. A reverse proxy requires 80 and 443 in order to obtain certificates and properly route traffic. Unless you decide not to use a reverse proxy, these must be changed to successfully complete this guide.
- RECOMMENDATION: Even if you do not use a reverse proxy, I HIGHLY recommend that you change the default ports for the Web UI, Web Server, and SSH connections to increase the security of your NAS. Also disable UPnP.
-
Modify the default ports as follows to ensure there will be no port conflicts with docker stacks:
- Change default System ports: In QNAP Web GUI
Control Panel >> System >> General Settings
- Change the default HTTP port to
8480
, and the default HTTPS port to8443
. - NOTE: This will change the LAN address from which you access your QTS web-gui, requiring you to add the port at the end of your NAS LAN IP (e.g. https://192.168.1.100:8443)
- Change default Web Application ports: In QNAP Web GUI
Control Panel >> Applications >> Web Server
- Change the default HTTP port to
9480
, and the default HTTPS port to9443
. - TIP: Unless currently in use, consider disabling the MySQL application in the QNAP GUI Settings.
- NOTE: Prior to version 5.x it is required to keep the Web Server application enabled with the modified ports, otherwise the QTS Web Server would re-acquire the default port when disabled.
- Change default SSH port: In QNAP Web UI
Control Panel >> Network & File Services >> Telent / SSH
- Change the default to a random number somewhere between
49152 - 65535
. - See this list of port numbers to make sure the one you choose is not already assigned.
- Change default System ports: In QNAP Web GUI
-
In order to use a reverse proxy, ports 80 and 443 must be forwarded from your router to your NAS.
-
WARNING: Only configure this port forward if you are using a reverse proxy such as Traefik, Caddy, or NXPM.
-
Disable UPnP on you router and manually forward ports 80 and 443 to your NAS.
-
NOTE: There are too many possible routers to cover how to forward ports on each, but there are some good guides here if you don't know how to do it for your router:
-
https://www.howtogeek.com/66214/how-to-forward-ports-on-your-router
-
https://portforward.com/router.htm
- WARNING: Do not purchase the port-forwarding program offered from this website, it will not work for this and is a waste of money.
-
-
-
TIP: During QTS initialization, if the first user created is the
dockeruser
user account, all the container configs shared here will be pre-configured to use the correctUID: 1000
andGID: 1000
. -
NOTE: If you do not create the
docker
user as the first user account, you will need to update each container config to reflect your particularUID
andGID
, obtained by the terminal command:id dockeruser
.
-
Ensure the
docker
user account is created.Control Panel >> Privilege >> Users
- Click the
Create
dropdown button and selectCreate User
. TIP: Create the user with all lowercase letters so Linux case sensitivity is never an issue.
-
Create a new group called
docker
. NOTE: This step can be performed after creation of the/docker
Shared Folder below in the5. Docker Folder Creation
section.Control Panel >> Privilege >> User Groups
- Click the
Create
button and type in thedocker
name. TIP: Create the user with all lowercase letters so Linux case sensitivity is never an issue. - Assign the
docker
user account to this group by clicking theEdit
button on the right. - If the
/docker
Shared Folder has been created, assignread/write
folder permissions for this group to the folder.
-
Install the
entware-std
package from the third-party QNAP Club repository appstore. This is necessary in order to set up the shortcuts/aliases used when controlling docker via command line by editing a permanent profile.-
The preferred way to do this is to add the My QNAP (formerly QNAP Club) Repository to the App Center. Follow the walkthrough instructions here.
Note, I use the English translation of the My QNAP website, but you may change languages (and urls) in the upper right language dropdown.
-
If you don't need the walkthrough, add the repository. For English, go to App Center, Settings, App Repository, paste in
https://www.myqnap.org/repo.xml
. -
If you cannot add the QNAP Club store to the App Center, you may manually download the qpkg file from that link and use it to manually install via the App Center, "Install Manually" button. This is not preferred as QNAP cannot check for and notify you of updates to the package.
-
Search for
entware-std
and install the package.TIP: If you have trouble locating the correct package, the description begins with
entware-3x and entware-ng merged to become entware.
The working link (as of publication) is here: https://www.myqnap.org/product/entware-std/ -
IMPORTANT: DO NOT install the
entware-ng
orentware-3x-std
packages. These have merged and been superceded byentware-std
.
-
-
Backup what you have running now (if you don't have anything running yet, skip to Step 3. If you have also never used Container Station, skip to Step 5).
-
Shutdown and remove all docker containers and networks. This can be accomplished using Container Station, but connecting via SSH terminal allows you to complete this quickly with only three commands.
-
Stop all running containers:
docker stop $(docker container ls --all --quiet)
-
Remove all stopped containers, unused networks, images, and build cache:
docker system prune
-
Ensure you are not a part of a Docker Swarm:
docker swarm leave --force
-
-
Remove Container Station:
-
Reboot the NAS
-
Once the reboot is complete, install Container Station from the QNAP Appstore.
- Launch CS after installed.
- Create the
container/
folder when prompted during the first launch of CS.
-
Create the
docker/
folder share using the QTS Web UI-
ControlPanel >> Privilege >> Shared Folders
-
Click the 'Create' dropdown button and select
Shared Folder
. -
Name the folder
docker
using all lowercase letters.WARNING: An all lowercase
docker
folder is required so the helper scripts work correctly. -
Give
dockeruser
Read/Write permissions for the newly created/docker
shared folder: -
INFO: This is the main "docker" folder inside which we will place swarm and compose config files in their own subfolders, as well as helper scripts and secrets. The remaining folders listed below should be created using the Terminal while logged in using the default QTS
admin
account. -
NOTE: The
appdata
,compose
,secrets
, andswarm
sub-folders can be created using QTS File Station, but that is entirely unnecessary considering you can create them all with a single terminal command shown below. They should not be created as Shared Folders in the same way as the parentdocker/
folder.
-
All actions in this section will be accomplished via SSH terminal connection to your QNAP NAS.
-
Open/Connect an SSH terminal session to your QNAP NAS.
- NOTE: Alternatively you can use BitVise because this also has an SFTP remote file browser interface.
- TIP: I switched to using WinSCP and Cmder because they have dark themes. Windows Terminal Preview is turning out to be a good Terminal as well.
- TIP: Connecting to the NAS using SFTP allows me to edit the docker config files using
Notepad++
orVSCodium
(open source Visual Studio Code clone). - TIP: I also map the
/share/docker/
folder as a Network drive on my Windows desktop, which makes viewing and editing Docker config files very easy.
-
Install
nano
so you can edit text files in the terminal: NOTE: You must have installedentware-std
as detailed in Section 1.4 and rebooted to be able to use the "opkg" installer command.- RUN:
opkg install nano
- RUN:
-
This section is a continuation of the QNAP QTS folder creation steps from the previous section. Here we will create required sub-folders in the
docker/
Shared Folder. -
Before creating the folders, these descriptions will familiarize you with the structure.
/share/docker/appdata
- This is where
application
data and internal config files will reside. - Each docker
container
will have its own named subfolder.
/share/docker/compose
- This is where
Docker stack
files will be stored using the docker compose format. - Each
compose
file can have multiple apps or containers included in the stack. - A git repository can provide versioning and backup for this folder.
- Do not save sensitive data in compose.yml files if this is a git repository.
/share/docker/runtime
- OPTIONAL.
Temporary
DB files andtranscode
files will go here. - This folder should reside on a volume that does not get backed up.
- Link this folder to a fast storage volume or Qtier cache if possible.
- If used, create with
ln -s /target/volume/path /share/docker/runtime
/share/docker/scripts
- Docker helper scripts for convenient container management are stored here.
- Read and update the
.vars_docker.env
file with your configuration info. - These scripts are why folder paths and compose files have strict naming requirements.
/share/docker/secrets
- This folder contains
secret
orsensitive
configuration data such as passwords. - Do not store this folder in a public git repository.
- Non-sensitive,
common
configuration settings can also be stored here.
/share/docker/swarm
- This is where
Swarm stack
files will be stored using the docker compose format. - Each
compose
file can have multiple apps or containers included in the stack. - A git repository can provide versioning and backup for this folder.
- Do not save sensitive data in compose.yml files if this is a git repository.
- This is where
-
The required subfolders should be created using this terminal command:
- QNAP ONLY: A link from
/opt/docker
to/share/docker
is required for script operations.ln -s /share/docker /opt/docker
TIP: Change
-o 1000
to your docker userUID
and-g 1000
to your docker groupGUID
.install -o 1000 -g 1000 -m 755 -d /share/docker/{appdata,compose,scripts,secrets,swarm}
-
Once required folders are created, make sure all files and sub-folders inside
docker/
are owned by thedockeruser
and have the proper permissions:chown dockeruser:dockergroup -cR /opt/docker && chmod 755 -cR /opt/docker
- This is what your folder heirarchy should show after creating the required folders:
# Docker folder heirarchy /share └── docker ├── appdata │ ├── appname │ └── ... ├── compose │ ├── appname │ └── ... ├── runtime ├── scripts ├── secrets └── swarm ├── appname └── ...
- Viewed through WinSCP, which shows the volume designation:
- This is what your folder heirarchy should show after creating the required folders:
- QNAP ONLY: A link from
-
Next you need to download the
docker helper scripts
from this QNAP HomeLAB Docker Scripts repository to your/share/docker/scripts/
directory.
WARNING: The automatic install script is not working, please download and install the scripts manually.
-
Alternatively, if you trust my installation script to run as root on your system, you can run thiscurl
command that will automatically download and install the scripts for you: -
TIP: Read through and understand what a script does before executing possibly malicious code on any device.
# install the docker_scripts_setup.sh using wget without downloading the file wget -qO - https://raw.githubusercontent.com/qnap-homelab/docker-scripts/master/docker_scripts_setup.sh | sh
OR
# download and install the docker_scripts_setup.sh using cURL curl -fs https://gitlab.com/qnap-homelab/docker-scripts/docker_scripts_setup.sh | sh
- Type the below lines into the QNAP command line. These commands will add a shortcut to reload the
profile
and make the docker scripts load each time you connect via SSH terminal.printf "\nalias profile='source /opt/etc/profile'" >> /opt/etc/profile
printf "\nsource /opt/docker/scripts/docker_commands_list.sh -c" >> /opt/etc/profile
-
NOTE: If you prefer to enter the text manually, these are the lines that need to go at the bottom of the
profile
file:alias profile='source /opt/etc/profile' source /opt/docker/scripts/docker_commands_list.sh -c
-
OPTIONAL: The below steps accomplish the same thing as above, but add notification messages whenever you reload or log into the qnap cli.
-
EDIT the
profile
file vianano /opt/etc/profile
orvi /opt/etc/profile
-
NOTE: I prefer to use VSCodium to edit this file as it provides syntax highlighting.
source /opt/docker/scripts/docker_commands_list.sh -c && echo " >> '.../docker_commands_list.sh' successfully loaded" || echo " -- ERROR: could not import '.../docker_commands_list.sh'"
-
NOTE: You will need to restart your ssh terminal session, or execute the
profile
alias (a shortcut to reloadprofile
), in order to make the changes effective.
-
WARNING:
If you use a Windows client to save the profile (or the scripts below),
by default the files will be saved with the CR LF
end of line sequence,
and will error when executed.
You MUST set the end of line sequence to UNIX LF
.
Windows CR LF
style EoL will result in failed scripts with no error.
-
Once the
profile
and/share/docker/scripts
are set up, use the below section as a reference for Docker shortcut commands.-
In general, this is the scheme for how the shortcut acronyms are composed:
dc...
refers to "Docker Compose" commands, for use outside of a swarm setupdl...
refers to "Docker List" commands (i.e. docker processes, docker networks, etc)ds...
refers to "Docker Stack" commands (groups of containers in a swarm setup)dv...
refers to "Docker serVice" commands (mostly error and logs related)dw...
refers to "Docker sWarm" initialization/removal commands (the whole swarm)dy...
refers to "Docker sYstem" commands for showing info and cleaning remnants
-
- NOTE: Individual script descriptions have been removed from this
readme.md
. Please refer to the docker_commands_list.sh file for an updated list with descriptions.
All instructions in this section will apply to your chosen Docker environment.
-
The Docker helper scripts require several environment variable to be properly configured.
-
The
.vars_docker.env
file has variables used by both Swarm and Compose containers. -
Ensure this file is located here:
/share/docker/scripts/.vars_docker.env
-
Read through this file, and fill in YOUR NETWORK, NAS, OR PERSONAL INFORMATION.
-
Pay special attention to these variables, as they are REQUIRED:
-
var_host_ip
- this is the Local Area Network IP address of your QNAP -
var_uid
- userid from commandid dockeruser
-
var_gid
- groupid from commandid dockeruser
-
var_tz
- time zone in standardRegion/City
format -
var_domain0
- main, or only, domain name used by Traefik -
var_dns_provider
- DNS provider (e.g. Cloudflare, Namecheap, etc) -
var_certresolver
- Certificate Resolver (e.g. Cloudflare, Namecheap, etc)
-
-
There are many more variables, but not all will be used for each new container created.
-
-
The basic setup is now complete. Continue in one of the two (or a combination of both!) linked repositories below to further customize your Docker environment.
I recommend the
Docker Swarm
setup, as it is considered a production environment. Docker Compose files can still be used in a Docker Swarm, but not all features of a Swarm can be used in the basic Compose setup.Once these environment specific steps are completed, you will be ready to customize
Traefik
and other Docker container configuration files also found in the repositories below.Download and modify the desired Docker container config files, or write your own.
- Final required steps and example application configuration files from QNAP HomeLAB:
- QNAP HomeLAB Docker Compose Configs - No further system configuration required.
docker-compose.yml
files can be used to immediately run containerized applications. - QNAP HomeLAB Docker Swarm Configs - Several more system configuration steps are required before you can run containerized applications using a Swarm setup.
- QNAP HomeLAB Docker Compose Configs - No further system configuration required.
If you have questions or issues, please join the community here: QNAP Unofficial Discord.
- Thanks to the late
gkoerk
(RIP) for starting this community and project. Without his efforts, none of this would have been possible. - Funky Penguin at funkypenguin.co.nz provided a lot of the inspiration and docker config examples which started this QNAP specific project.
- Several articles from smarthomebeginner.com were used as reference for the Traefik and Cloudflare configuration steps contained in the next two sections of this guide.
- The many helpers and members in the QNAP Unofficial Discord community.
- WARNING: This guide is incomplete, and as such will probably contain errors.
- NOTE: Effort has been made to provide accurate instructions tailored for QNAP NAS devices, but no guarantee can be made that this guide will work on your specific device.
-
I find it unfortunate that I have to say this, but you must accept all liability for any loss or damage or inconvenience resulting from your use of the information contained in these guides.
-
All responsibility and risk for properly verifying the validity of anything written in this guide lies with the user.
-
Contributors have composed the steps contained herin to the best of their ability, but nobody is infallible nor can all situations be accounted for.
-
If you have questions or concerns, please join us on the QNAP Unofficial Discord community and request help.
-