Ferdous Azad
Posted on June 16, 2024
Docker is a platform for developing, shipping, and running applications in containers. Containers are lightweight and contain everything needed to run an application, making them portable and consistent across environments.
Here’s a brief tutorial on Docker, including creating containers, networking between containers, and setting up a simple multi-container application involving a database, cache, and services written in Node.js and Go.
1. Install Docker
Install Docker from Docker’s official website
2. Basic Docker Commands
Pull an image:
docker pull <image-name>
Example:
docker pull node:14
Run a container:
docker run -d – name <container-name> <image-name>
Example:
docker run -d – name my-node-container node:14
List running containers:
docker ps
Stop a container:
docker stop <container-name>
Remove a container:
docker rm <container-name>
3. Creating a Node.js Application Container
Create a simple Node.js application:
mkdir node-app
cd node-app
npm init -y
npm install express
2. Create app.js
:
const express = require(‘express’);
const app = express();
const PORT = 3000;
app.get('/', (req, res) => {
res.send('Hello from Node.js!');
});
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}`);
});
3. Create `Dockerfile:
Dockerfile
`
FROM node:14
WORKDIR /usr/src/app
COPY package.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD ["node", "app.js"]
`
4. Build the Docker image:
docker build -t node-app .
5. Run the container:
docker run -d – name node-app-container -p 3000:3000 node-app
Creating a Go Application Container
Create a simple Go application:
mkdir go-app
cd go-app
2. Create main.go
:
`
package main
import (
"fmt"
"net/http"
)
func handler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello from Go!")
}
func main() {
http.HandleFunc("/", handler)
http.ListenAndServe(":8080", nil)
}
`
3. Create Dockerfile
:
Dockerfile
`
FROM golang:1.16
WORKDIR /app
COPY . .
RUN go build -o main .
EXPOSE 8080
CMD ["./main"]
`
4. Build the Docker image:
docker build -t go-app .
5. Run the container:
docker run -d – name go-app-container -p 8080:8080 go-app
5. Setting Up a Database Container
Run a PostgreSQL container:
docker run -d – name postgres-container -e POSTGRES_PASSWORD=mysecretpassword -e POSTGRES_DB=mydatabase -p 5432:5432 postgres
6. Setting Up a Redis Cache Container
Run a Redis container:
docker run -d – name redis-container -p 6379:6379 redis
7. Networking Between Containers
Docker provides several ways to network containers. The simplest way is to use Docker’s default bridge network.
Create a custom network:
docker network create my-network
2. Run containers in the same network:
docker run -d – name postgres-container – network my-network -e POSTGRES_PASSWORD=mysecretpassword -e POSTGRES_DB=mydatabase postgres
docker run -d – name redis-container – network my-network redis
docker run -d – name node-app-container – network my-network -p 3000:3000 node-app
docker run -d – name go-app-container – network my-network -p 8080:8080 go-app
8. Connecting Services to Database and Cache
Example Node.js (app.js) connecting to PostgreSQL and Redis:
Install dependencies:
npm install pg redis
Modify app.js
:
`
const express = require('express');
const { Pool } = require('pg');
const redis = require('redis');
const app = express();
const PORT = 3000;
const pool = new Pool({
user: 'postgres',
host: 'postgres-container',
database: 'mydatabase',
password: 'mysecretpassword',
port: 5432,
});
const client = redis.createClient({
host: 'redis-container',
port: 6379,
});
app.get('/', async (req, res) => {
const result = await pool.query('SELECT NOW()');
client.set('key', 'value');
client.get('key', (err, value) => {
res.send(PostgreSQL time: ${result.rows[0].now}, Redis value: ${value}
);
});
});
app.listen(PORT, () => {
console.log(Server is running on port ${PORT}
);
});
`
Example Go (main.go
) connecting to PostgreSQL and Redis:
Install dependencies:
go get github.com/lib/pq
go get github.com/go-redis/redis/v8
2. Modify main.go
:
`
package main
import (
"context"
"database/sql"
"fmt"
"net/http"
"github.com/go-redis/redis/v8"
_ "github.com/lib/pq"
)
var ctx = context.Background()
func handler(w http.ResponseWriter, r *http.Request) {
connStr := "user=postgres password=mysecretpassword dbname=mydatabase host=postgres-container sslmode=disable"
db, err := sql.Open("postgres", connStr)
if err != nil {
panic(err)
}
defer db.Close()
var now string
err = db.QueryRow("SELECT NOW()").Scan(&now)
if err != nil {
panic(err)
}
rdb := redis.NewClient(&redis.Options{
Addr: "redis-container:6379",
})
err = rdb.Set(ctx, "key", "value", 0).Err()
if err != nil {
panic(err)
}
val, err := rdb.Get(ctx, "key").Result()
if err != nil {
panic(err)
}
fmt.Fprintf(w, "PostgreSQL time: %s, Redis value: %s", now, val)
}
func main() {
http.HandleFunc("/", handler)
http.ListenAndServe(":8080", nil)
}
`
9. Docker Compose
To simplify the process, you can use Docker Compose to define and run multi-container Docker applications.
Create docker-compose.yml
:
`
version: '3'
services:
postgres:
image: postgres
environment:
POSTGRES_PASSWORD: mysecretpassword
POSTGRES_DB: mydatabase
networks:
- my-network
redis:
image: redis
networks:
- my-network
node-app:
build: ./node-app
ports:
- "3000:3000"
networks:
- my-network
go-app:
build: ./go-app
ports:
- "8080:8080"
networks:
- my-network
networks:
my-network:
driver: bridge
`
Run the application:
docker-compose up – build
By following this tutorial, you can set up a multi-container application with Docker, including networking between containers and connecting services to a database and cache.
Posted on June 16, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.