Deploying Dart and Flutter Apps with Docker: VPS Setup Made Simple
Introduction
Welcome to the last part of my series on deploying Dockerized Dart containers on Ubuntu VPS. This series is designed to guide you through every step of the process, from selecting the most cost-effective infrastructure to creating Docker images and setting up your server for deployment. By the end of it, you'll have the knowledge and confidence to deploy robust Dart & Flutter applications in a production environment.
In this article, I’ll focus on deploying your Dockerized Dart code to Ubuntu VPS. It will include the whole setup of the VPS, how to deploy it, and some additional things you can use to make this process easier.
The process looks like this:
- Prepare the docker image
- Setup ssh to the VPS
- Install Docker
- Deploy the Docker image
- Setup firewall
- Setup Reverse Proxy with Caddy
- Setup domain A records
Before starting make sure you can log in into your VPS by using username and password or SSH and create a Docker Hub account if you don’t have it.
Ready to get your hands dirty?
Let’s start.
1. Prepare the Docker Image
Preparing the Docker image consists of 3 parts:
- Building the image
- Tagging the image
- Pushing the image to the repository
Make sure you are logged into your DockerHub account on Docker Desktop before starting to build the image
To build your Docker image, navigate to the directory containing your Dockerfile and run:
docker build -t your-username/your-dart-app .
Next, we have to tag the image to assign a version to it. Tag your image as follows:
docker tag your-username/your-dart-app:latest your-username/your-dart-app:v1.0.0
The last step is pushing the image to a container registry (Docker Hub in our case) so it can be pulled later on your VPS:
docker push your-username/your-dart-app:v1.0.0
2. Setup SSH to the VPS
To securely connect to your VPS, you need to set up SSH. Assuming you already have SSH keys generated, use the following command to copy your public key to the VPS:
ssh-copy-id username@your-vps-ip
Verify the connection:
ssh username@your-vps-ip
If you don’t have SSH key generated, please follow this guide.
2.1 Install SSH on Ubuntu (if not installed)
If SSH is not already installed on your Ubuntu VPS, you can install it by running:
sudo apt update
sudo apt install openssh-server
Enable and start the SSH service:
sudo systemctl enable ssh
sudo systemctl start ssh
Check the status to ensure SSH is running:
sudo systemctl status ssh
3. Install Docker
Once connected to your VPS, install Docker using the following commands:
sudo apt update
sudo apt install apt-transport-https ca-certificates curl software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update
sudo apt install docker-ce
Verify the installation:
sudo systemctl status docker
Optionally, you can also install Docker using snap:
sudo snap install docker
Installing Docker using snap comes with some drawbacks, but since we are only using basic Docker stuff in this tutorial, you should be fine with a snap install.
4. Deploy Docker image
To deploy the image, we need to pull the image from the repository and run the container.
Pull the Docker image from Docker Hub:
docker pull your-username/your-dart-app:v1.0.0
Run the container from the pulled image:
docker run -d -p 8080:8080 --name dart_app your-username/your-dart-app:v1.0.0
Pay attention to what port your app uses in the main.dart
file and what port you exposed in the Dockerfile
. If these are not both 8080, make sure to use the proper ports otherwise you will not be able to access the app from outside of the container.
5. Setup Firewall
Ensure your firewall allows traffic on the required ports. If you are using UFW (Uncomplicated Firewall), configure it as follows:
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
6. Setup Reverse Proxy with Caddy
A reverse proxy is a server that sits in front of web servers and forwards client (e.g. web browser) requests to those web servers. Reverse proxies are typically implemented to help increase security, performance, and reliability.
By default, your Dart server will serve content using the HTTP protocol, which is not secure. To be able to use HTTPS you will need certificates. You will also want to connect your domain to forward the request to your Dart server.
Most of the tutorials out there will advise you to use a combination of Nginx Proxy Manager and Certbot to setup reverse proxy and certificates management. These are very powerful tools that require some setup, but there is another tool more suited to just serving a couple of addresses on HTTP and it’s called Caddy.
Caddy is a powerful, enterprise-ready, open-source web server with automatic HTTPS written in Go. To install Caddy, follow these steps:
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo apt-key add -
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo apt update
sudo apt install caddy
Configure Caddy to proxy requests to your Dart application. Create a Caddyfile at /etc/caddy/Caddyfile
with the following content:
your-domain.com {
reverse_proxy localhost:8080
}
Restart Caddy to apply the changes:
sudo systemctl restart caddy
7. Setup Domain A Records
Finally, you need to point your domain to your VPS. Go to your domain registrar's DNS management page and add an A record:
- Type: A
- Name: @ (or your subdomain, e.g., www)
- Value: Your VPS IP address
- TTL: Automatic or 1 hour
Please follow one of these detailed guides according the domain registrar you used to buy your domain: Namecheap, Cloudflare or Porkbun.
After the DNS changes propagate, your Dart application will be accessible via https://your-domain.com
.
Optional
Depending on your needs, you might want to make a couple of additional changes to the VPS setup:
- Setup automatic Docker pull with Watchtower
- Setup DDOS protection using Cloudflare
- Remove username access on the VPS (leaving on SSH as an option to access it)
- Setup advanced Firewall settings
Conclusion
Congratulations, you have successfully deployed a Dart application in a Docker container to a VPS using Ubuntu. Your application is now secured with HTTPS thanks to Caddy, and accessible via a domain name. This setup ensures a scalable and secure environment for your Dart application.
If you have read and used all 3 parts of the series, I want to applaud you for your perseverance and dedication. Deployment is not an easy task at first, but once you’ve tried it, you will realize it’s not that hard either.
If you have found this useful, make sure to like and follow for more content like this. To know when the new articles are coming out, follow me on Twitter or LinkedIn.
Subscribe to my newsletter
Read articles from Dinko Marinac directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Dinko Marinac
Dinko Marinac
Mobile app developer and consultant. CEO @ MOBILAPP Solutions. Passionate about the Dart & Flutter ecosystem.