DEV Community

Cover image for Docker a beginners guide
Ferdous Azad
Ferdous Azad

Posted on

Docker a beginners guide

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
Enter fullscreen mode Exit fullscreen mode

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}`);
});
Enter fullscreen mode Exit fullscreen mode

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.

Top comments (0)