In the previous post, we mentioned about the Docker tutorial in.
This time, we are starting to run sample projects: Focusing on the Docker Compose file with Nodejs, Flask, PostgreSQL images to implement different tiers:
- frontend (nodejs with expressjs),
- backend (flask),
- database (postgresql).
It shows:
- how to run multiple containers
- how to run container in sequential with
depends_on
- how to run containers in same network
- how to create volumes in compose file
- how to implement port-forwarding
GitHub Code Repo: https://github.com/omerbsezer/Fast-Docker/tree/main/hands-on-sample-projects/full-stack-app
Project structure:
project-root/
├── docker-compose.yaml
├── frontend/
│ ├── package.json
│ ├── index.js
│ ├── index.html
│ ├── Dockerfile
├── backend/
│ ├── app.py
│ ├── requirements.txt
│ ├── Dockerfile
- Create frontend directory, create Dockerfile:
FROM node:18
WORKDIR /home/app
COPY . .
EXPOSE 3000
RUN npm install
CMD ["npm", "start"]
- Create index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Frontend</title>
</head>
<body>
<h1>Frontend is working!</h1>
</body>
</html>
- Create index.js (express js):
const express = require("express");
const app = express();
const port=3000;
app.get("/", (req, res) => {
res.sendFile(__dirname + "/index.html");
})
app.listen(port, () => {
console.log(`running at port ${port}`);
});
- Create package.json:
{
"name": "nodejsapp",
"version": "1.0.0",
"description": "nodejsapp description",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "node index.js"
},
"author": "",
"license": "ISC",
"dependencies": {
"express": "^4.17.3"
}
}
- Then, create backend directory, and create Dockerfile:
FROM python:3.11
WORKDIR /usr/src/app
COPY . .
RUN pip install -r requirements.txt
EXPOSE 5000
CMD ["python", "app.py"]
- Create backend app with flask:
from flask import Flask, jsonify
app = Flask(__name__)
@app.route('/')
def home():
return "Backend is working!"
@app.route('/api', methods=['GET'])
def api():
return jsonify({"message": "Hello from the backend!"})
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)
- Create requirements.txt:
flask
- Finally create docker-compose.yaml on top of backend and frontend directories:
services:
frontend:
build:
context: ./frontend
container_name: frontend
ports:
- "3000:3000"
volumes:
- ./frontend:/usr/src/app
depends_on:
- backend
backend:
build:
context: ./backend
container_name: backend
ports:
- "5000:5000"
volumes:
- ./backend:/usr/src/app
command: sh -c "pip install -r requirements.txt && python app.py"
db:
image: postgres:15
container_name: db
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: password
POSTGRES_DB: mydatabase
volumes:
- db_data:/var/lib/postgresql/data
ports:
- "5432:5432"
volumes:
db_data:
- Then, run command on where the docker-compose.yaml:
user@docker:~$ docker compose up -d
[+] Running 4/4
✔ Network node_default Created 0.1s
✔ Container db Started 0.7s
✔ Container backend Started 0.7s
✔ Container frontend Started
- Then, check frontend, backend with curl:
user@docker:~$ curl http://localhost:3000
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Frontend</title>
</head>
<body>
<h1>Frontend is working!</h1>
</body>
user@docker:~$ curl http://localhost:5000/api
{"message":"Hello from the backend!"}
user@docker:~$ curl http://localhost:5000
Backend is working!
</html>
- Finally, stop containers:
user@docker:~$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3e51751b546c node-frontend "docker-entrypoint.s…" About a minute ago Up About a minute 0.0.0.0:3000->3000/tcp, :::3000->3000/tcp frontend
d8d28325ce10 postgres:15 "docker-entrypoint.s…" About a minute ago Up About a minute 0.0.0.0:5432->5432/tcp, :::5432->5432/tcp db
04c1d04a5668 node-backend "sh -c 'pip install …" About a minute ago Up About a minute 0.0.0.0:5000->5000/tcp, :::5000->5000/tcp backend
user@docker:~$ docker compose down
[+] Running 4/4
✔ Container frontend Removed 1.0s
✔ Container db Removed 0.5s
✔ Container backend Removed 10.5s
✔ Network node_default Removed 0.2s
user@docker:~$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
Conclusion
This post shows how to create Docker compose file using sample frontend (express.js), backend (flask), database (postgresql) apps. Please have a look below menu for other Docker content, if you haven't seen before.
If you found the tutorial interesting, I’d love to hear your thoughts in the blog post comments. Feel free to share your reactions or leave a comment. I truly value your input and engagement 😉
Follow for Tips, Tutorials, Hands-On Labs for AWS, Kubernetes, Docker, Linux, DevOps, Ansible, Machine Learning, Generative AI, SAAS.
Top comments (0)