Repository navigation
04‐ Containerizing the User Service with Docker
Rabieh Fashwall edited this page Jan 22, 2025
·
4 revisions
We'll containerize our User service using Docker and introduce Viper for environment-based configuration. We'll create a Dockerfile to build a Docker image of our service and use Docker Compose to define and run our User service along with a MySQL database.

By the end of this branch, you'll be able to:
- Use Viper to manage environment variables for your User service.
- Build a Docker image for your User service.
- Define and run the User service and MySQL database using Docker Compose.
-
Create Branch:
git checkout 03-add-env-variables-and-dockerise
-
Install Viper:
go get github.com/spf13/viper
-
Update
user-service/cmd/main.goto use Viper for Configuration:- Import the Viper package.
- Configure Viper to read from environment variables.
- Access database configuration from environment variables using Viper.
func main() { // Configure Viper to read from environment variables. viper.SetEnvPrefix("USER_SERVICE") // Set environment variable prefix viper.AutomaticEnv() // Enable Viper to read from environment variables. // Database Configuration from Environment Variables dbHost := viper.GetString("DB_HOST") dbPort := viper.GetString("DB_PORT") dbUser := viper.GetString("DB_USER") dbPass := viper.GetString("DB_PASS") dbName := viper.GetString("DB_NAME") // ... (Rest of the main function) }
-
Create a Dockerfile (
user-service/Dockerfile):FROM golang:1.23.4-alpine WORKDIR /app COPY . . RUN go mod tidy RUN go build -o user-service ./cmd CMD ["./user-service"]
-
Create a Docker Compose File (
docker-compose.yaml):
version: '3.8'
services:
user-service:
build:
context: ./user-service
dockerfile: Dockerfile
container_name: user-service
ports:
- "3000:3000"
environment:
- USER_SERVICE_DB_HOST=mysql-server
- USER_SERVICE_DB_PORT=3306
- USER_SERVICE_DB_USER=root
- USER_SERVICE_DB_PASS=root
- USER_SERVICE_DB_NAME=user_tracker
depends_on:
- mysql-server
mysql-server:
image: mysql:latest
container_name: mysql-server
restart: always
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: user_tracker
ports:
- "3306:3306"
volumes:
- mysql_data:/var/lib/mysql
- ./init.sh:/docker-entrypoint-initdb.d/init.sh
healthcheck:
test: ["CMD-SHELL", "mysqladmin ping -h localhost"]
interval: 10s
retries: 5
start_period: 30s
timeout: 10s
volumes:
mysql_data:
- Create init.sh to setup the DB
#!/bin/bash
set -e
mysql -u root -proot <<-EOSQL
CREATE DATABASE IF NOT EXISTS user_tracker;
USE user_tracker;
CREATE TABLE IF NOT EXISTS users (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
email VARCHAR(100) NOT NULL UNIQUE,
password VARCHAR(255) NOT NULL
);
CREATE DATABASE IF NOT EXISTS task_tracker;
USE task_tracker;
CREATE TABLE IF NOT EXISTS tasks (
id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT NOT NULL,
assignee_id INT NULL,
title VARCHAR(255) NOT NULL,
description TEXT,
status VARCHAR(50)
);
EOSQL
-
Run the Application using Docker Compose:
docker-compose up -d --build
-
-d: Runs the containers in detached mode (in the background). -
--build: Forces Docker Compose to rebuild the images even if they already exist.
-
- Once the containers are running, you can use the same
curlcommands as before to test the API endpoints. The only difference is that you should now send the requests tohttp://localhost:3000since the User service's port is mapped to port 3000 on your host machine.