
Setting Up a Web Application Stack with Docker on Ubuntu VPS
Setting Up a Web Application Stack with Docker on Ubuntu VPS
Introduction
In this tutorial, you’ll learn how to set up a web application stack on a VPS using Docker. We will deploy a simple Node.js application with Express and MongoDB as the database. Docker allows you to containerize your applications, making them portable and easy to manage.
Table of Contents
TogglePrerequisites
- A VPS running Ubuntu 20.04 or later.
- SSH access to your server.
- Basic knowledge of command-line operations.
Step 1: Connect to Your VPS
First, open your terminal and connect to your VPS via SSH:
ssh username@your_server_ip
Replace username
with your actual username and your_server_ip
with your VPS’s IP address.
Step 2: Update Your System
Once connected, it’s a good practice to update your system:
sudo apt update && sudo apt upgrade -y
Step 3: Install Docker
Next, we will install Docker, which allows us to run applications in containers.
- Install required packages:
sudo apt install apt-transport-https ca-certificates curl software-properties-common -y
- Add the Docker GPG key:
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
- Add the Docker APT repository:
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
- Update the package index again:
sudo apt update
- Install Docker:
sudo apt install docker-ce -y
- Verify that Docker is installed:
sudo systemctl status docker
You should see that the Docker service is active and running.
Step 4: Install Docker Compose
Docker Compose is a tool for defining and running multi-container Docker applications. To install it:
- Download the Docker Compose binary:
sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
- Set permissions:
sudo chmod +x /usr/local/bin/docker-compose
- Check the installed version:
docker-compose --version
Step 5: Create a Sample Node.js Application
Now that Docker is installed, let’s create a simple Node.js application.
- Create a project directory:
mkdir my-node-app && cd my-node-app
- Create a
package.json
file:
npm init -y
- Install Express.js:
npm install express
- Create an
app.js
file:
nano app.js
Add the following code to set up a simple Express server:
const express = require('express');
const mongoose = require('mongoose');
const app = express();
const PORT = process.env.PORT || 3000;
// Middleware to parse JSON
app.use(express.json());
// Connect to MongoDB
mongoose.connect('mongodb://mongo:27017/mydatabase', {
useNewUrlParser: true,
useUnifiedTopology: true
});
// Define a simple route
app.get('/', (req, res) => {
res.send('Hello World from Node.js!');
});
// Start the server
app.listen(PORT, () => {
console.log(`Server is running on http://localhost:${PORT}`);
});
Step 6: Set Up Dockerfile
Next, we need to create a Dockerfile
to define how our Node.js application will run in a container.
- Create a
Dockerfile
:
nano Dockerfile
Add the following content:
# Use the official Node.js image
FROM node:14
# Set the working directory
WORKDIR /usr/src/app
# Copy package.json and install dependencies
COPY package*.json ./
RUN npm install
# Copy the application code
COPY . .
# Expose the application port
EXPOSE 3000
# Command to run the application
CMD ["node", "app.js"]
Step 7: Set Up MongoDB with Docker
We will run MongoDB in a separate container. To do this, create a docker-compose.yml
file:
- Create the
docker-compose.yml
file:
nano docker-compose.yml
Add the following content to define the services:
version: '3.8'
services:
mongo:
image: mongo:latest
container_name: mongo
ports:
- "27017:27017"
networks:
- my-network
web:
build: .
container_name: node-app
ports:
- "3000:3000"
depends_on:
- mongo
networks:
- my-network
networks:
my-network:
driver: bridge
Step 8: Build and Run the Application
Now, with everything set up, you can build and run your application using Docker Compose.
- Build the Docker images and start the containers:
docker-compose up --build
This command will build your Node.js application and start both the Node.js and MongoDB containers.
Step 9: Test Your Application
Once everything is running, you can test your application by visiting:
http://your_server_ip:3000
You should see the message “Hello World from Node.js!”.
Step 10: Manage Your Docker Containers
With Docker, managing your containers is straightforward. Here are some useful commands:
- List running containers:
docker ps
- Stop the containers:
docker-compose down
- Start the containers again:
docker-compose up
- View logs:
docker-compose logs
Step 11: Persist MongoDB Data
By default, MongoDB will store its data in a temporary volume, which means if you restart your containers, any data will be lost. To persist the data, you can modify the docker-compose.yml
file to include a volume for MongoDB.
mongo:
image: mongo:latest
container_name: mongo
ports:
- "27017:27017"
volumes:
- mongo-data:/data/db
networks:
- my-network
volumes:
mongo-data:
Step 12: Security Considerations
When deploying applications, security is crucial. Here are some practices to consider:
- Use environment variables for sensitive information like database credentials instead of hardcoding them in your application.
- Limit access to your MongoDB instance by configuring authentication.
- Set up a firewall (like UFW on Ubuntu) to restrict access to your server.
Step 13: Deploying to Production
For production deployment, consider the following:
- Use a reverse proxy like Nginx to handle incoming requests and route them to your Node.js application.
- Set up HTTPS to secure connections using Let’s Encrypt.
- Monitor application performance and logs to track any issues.
Conclusion
Congratulations! You’ve successfully set up a full web application stack using Docker on an Ubuntu VPS. You learned how to create a simple Node.js application, containerize it with Docker, and run it alongside MongoDB. This environment is ideal for development and can be extended for production use with some additional configurations.