I found a post here may help Securing Docker Ports with Firewalld (CentOS7, etc). Just post it here for people who need it in future.

For security concerns, we need both hardware and OS firewalls to be enabled and properly configured. I found that firewall protection is ineffective for ports that are opened in a Docker container and listened on 0.0.0.0, even though the firewalld service was enabled at that time.

My situation is :

It was expected that no one others could access port 3000 on that server, but the testing result was opposite. Port 3000 on that server was accessed successfully from any other servers. Thanks to the blog post, I have had my server under firewall protected.

Quoted from the post : Securing Docker Ports with Firewalld (CentOS7, etc)

Tested on CentOS7 with Docker-CE 18.09.6 Docker maintains IPTABLES chain "DOCKER-USER". If you restart firewalld when docker is running, firewalld is removing the DOCKER-USER chain, so no Docker access is possible after this. Docker adds a default rule to the DOCKER-USER chain which allows all IPs to access (possibly unsecure).

We can achive secured Docker ports maintained by firewalld by letting firewalld create the DOCKER-USER chain, then apply iptables direct rules to secure the docker ports in this chain. When Docker is then started, it adds its allow-all rule to the bottom of our chain, but as we add a reject-all rule before, this rule is not in effect.