preloader
心得

How to Let Docker Containers on Synology NAS Can Be Connected to Internet

How to Let Docker Containers on Synology NAS Can Be Connected to Internet

Many people have problems for setting connectivity between containers, home private network and Internet on Synology NAS. There’re few different points than normal linux systems such as Synology NAS has no built-in docker-compose program and it has the tricky firewall.

Below will use them as example:

  • docker images of postgresql A and express.js B from official on dockerhub
  • DSM 6.2.4-25556 Update 6
  • Reverse proxy server on DSM
  • Firewall on DSM
  • CloudFlare CDN A record
  • Wildcard ssl certificate from Let's encrypt

Build docker images

Important things at this section are exposing ports of containers. Docker image of postgresql exposes port 5432 default, and it needs some environment variables for setting. If you want to know more about them, please refer section of environment variables on Docker Hub. In description of this article, express.js is considered as exposing port 4000 at codebase.

Dockerfile of express.js

Because base image of node and postgres already expose port, I just use technique of multi-stage packaging about docker.

FROM node:XX.XX.X-alpineX.XX AS builder
ARG NODE_ENV=production

WORKDIR /usr/src/app

COPY package*.json ./
RUN npm install --legacy-peer-deps

# The instructions for second stage
FROM node:XX.XX.X-alpineX.XX

WORKDIR /usr/src/app
COPY --from=builder /usr/src/app/node_modules node_modules/

COPY . .

CMD [ "npm", "run", "start:prod" ]

I’m inspired and it should be credited to article of Alex Barashkov on dev.to: Using Docker for Node.js in Development and Production. This article shares benefit about short-time of re-packaging an image if there are only new features or bug-fixing be added to codebase and no new version of packages are introduced.

npm run start:prod should accompany with scripts in package.json file. Below are exerpted content of package.json.

// package.json

  "scripts": {
    "start:prod": "NODE_ENV=production node src/server.js",
  },


 

Setup of container network and NAS network

Pre-requirement of NAS network firewall

It should be set two rules in synology firewall in order. First rule is allowing source IP are 192.168.1.0/24 and they can reach all ports. Second rule is denying source IP range from all IPs and cannot reach all ports.

Remind: Control panel has firewall for setting.

NAS firewall fundamental rules

 

Create an user-defined bridge network on Docker

You must create an user-defined bridge network on Docker program because default bridge network has no DNS capability between docker containers. That’s mean containers cannot communicate with / connect to others' via containers' names.

Create an user-defined bridge network
  • Steps
    1. Click Docker program on Synology NAS
    2. Click Network tab.
    3. Click Create button on Network tab.
    4. Type network name you want, IP range(such as 172.17.0.1) and sub-network mask. In this example,, I use demo_network as an example.

 

Setup containers and attach their ports to the bridge network

Here I let docker image postgresql be container A and image express-server be container B. Container A uses port 5432 in user-defined bridge network. Container B uses port 4000 in user-defined bridge network and exposes port 40000 in home private network.

You can setup container by clicking launch button at images tab.

Setup container

Steps:

  1. Set container name. This can be used as connect with other containers.
  2. Set resource limit.
  3. Click Advance setting button for setting custom network, ports and other settings.
Setup container 1

 

Steps:

  1. At Advanced Settings tab, mark checked for option: auto-restart if you want container restart automatically.
  2. At Volume tab, mount any files or folder if you want container mount in any path and file.
  3. At Network tab, add only the user-defined bridge network you created and remove default bridge network.
  4. At Port-settings tab, add local port and container port you want with protocol type TCP/UDP. In example picture, I add both of TCP and UDP. Local port is used for NAS or other service can communicate with this container. Container port is used for other containers within same user-defined bridge network can communicate with this container.
  5. At Links tab, you have nothing to config because it can be set only this container is attached on default bridge network.
  6. At Environment tab, it’s optional setting if your container doesn’t need any environment variables during execution. If it requires some environment variables, you need to config it and its value. There is no limit about number of environment variables.

Setup container 2 - Advanced settings tab
Setup container 3 - Volume tab
Setup container 4 - Volume tab after adding some file or folder
Setup container 5 - Network tab
Setup container 6 - Port settings tab
Setup container 7 - Links tab
Setup container 8 - Environment tab
 

Create firewall rules for inter-communication of containers

Do you remember what ip range we assumed above for the user-defined network: demo_network? You need the ip range here and I assume you use same range mentioned above. Because in this example I just create two containers and first IP is reserved for gateway of the user-defined network whose has no extra or special setting, IPs of two containers, which are postgres(container A) and express-server(container B), are 172.17.0.2 and 172.17.0.3 respectively. I also let their ports on the user-defined network are 5432 and 4000.
Please add new rule for source from 172.17.0.0 and subnet mask 255.255.0.0. to firewall. This new rule is allowing to access ports of 5432 and 4000.

NAS firewall rule for intercommunication between containers

 

Create firewall rules between home private network and containers

Let’s assume your home private network is 192.168.1.0/24. Is it similar with NAS its network? Yes, that’s right, the NAS server is within home private network and be a node of them. Here I create new rule to firewall for allowing traffic as source IP is 172.17.0.3 can access port 40000 using TCP. This rule and its order lets container B can respond to any incoming requests. Combining it with one fundamental rule for 192.168.1.0/24, container B can interact with any request from home private network.
After finishing above, containers can communicate each other and can be connected within private network using private IP.

If I create new rule to firewall for allowing requests coming from Internet to access and also setup reverse proxy, container B can be accessed right? Yeah, you’re right. I will describe steps in next section.

 

Setup for Internet connectivity

Steps:

  1. Setting of mapping domain name and host network using reverse proxy server
  2. set certificate for domain. It would be better if you have the wildcard ssl certificate for your domain. So any sub-domain name you set on DNS will be covered.
  3. Setup of firewall rules.

Synology NAS has reverse proxy server service, you can use it. Its path is Control panel -> Application portal -> Reverse Proxy.

Path of NAS reverse proxy service entry

 

Create a record of reverse proxy server for container B and some domain name you want to mapping. After clicking create button at reverse proxy tab, you can type information of domain name and container B to the shown dialog. At general tab, you can:

  1. For description field, type any description you want.
  2. For source section, type the domain name you want to be mapped. Please remember use HTTPS protocol, port 443 and I recommend you mark checked two options: Enable HSTS and Enable HTTP/2.
  3. For destination section, use HTTP protocol, a NAS private IP(192.168.1.x, an ip NAS is using now) as hostname and container exposed port. For example here, port 40000 is the one of container B exposed to home private network. Here I use test.xxxxxx.cc as an example domain name.

Notice: Please make sure the domain name you actually own or on your rent period.

Create a reverse proxy record for container B

 

You can use your own ssl certificate. If you don’t have one, you should prepare formal one before doing this section. If you want to try free ssl certificates, I recommend you to try let's encrypt via acme.sh on synology NAS.
Steps:

  1. Usage path: Control panel -> Security -> Certificates -> click Configure button
  2. Select your own certificate for this above mentioned domain name. It’s better if it is the wildcard certificate for your domain. Notice: The wildcard ssl certificate is like *.xxxxxx.cc and it lets any sub domain name can use itself for https.

Setting certificate to a domain name
let your domain use wildcard ssl certificate

 

Create new firewall rule for allowing traffic from Internet to https reverse proxy service port 443. Just create new one as following one picture does.

Create new firewall rule for traffic between Internet and reverse proxy
 

Cloudflare’s DNS setting

It’s final part about connectivity and it’s so important for every request coming from Internet can use domain name to connect. Without this DNS setting, all Internet requests can only use IP to communicate to your NAS server. Here I use Cloudflare DNS setting as example, you can follow similar steps in any DNS service provider.

  1. Add the domain name and related IP you want, then set it to A record.
  2. Don’t forget mark checked for proxy during adding A record.
  3. Wait from 2 minutes to 10 minutes for taking the record effect
Create new A record in cloudflare DNS

 

Acknowledge

Thanks my friend icemango for kindly reminding me using command docker inspect to examine network connectivity between containers. So that I can investigate from little things to larger range. Initially, I was thought all problem comeing from the packages within docker images are too new and incompatible with latest node version(version 18 series). Actually, it’s part of unworkable reasons. After I downgrade environment version to be known as workable, express-server container still cannot connect to the other one. So I start to trouble-shoot network connectivity from little granularity to larger one.

Reference: