Getting Started with Docker: Setting Up a Full-Stack Application
If you’re a programmer looking to get started with Docker! In this guide, we’ll walk through setting up a project that uses Docker to manage a full-stack application. We’ll use React for the frontend, Ruby on Rails for the backend, MySQL as the database, and Elasticsearch for our search capabilities. Let’s dive in!
Folder Structure
First, we'll set up the folder structure for our project. Here's how it should look:
project-root/
├── frontend/
│ ├── Dockerfile
│ ├── package.json
│ └── src/
├── backend/
│ ├── Dockerfile
│ ├── Gemfile
│ ├── Gemfile.lock
│ └── config/
├── database/
│ └── my.cnf
├── elasticsearch/
│ └── Dockerfile
├── docker-compose.yml
└── README.md
Folder Explanation:
- frontend/: Contains all files related to the React frontend application.
- backend/: Contains all files for the Rails API backend.
- database/: Stores MySQL configuration files.
- elasticsearch/: Elasticsearch configuration and Dockerfile.
- docker-compose.yml: Defines the services for the application stack and how they interact.
Don’t stress too much if you’re missing some files initially. You can add them as you go along.
Setting Up Docker Containers
To manage all the different services, we’ll use Docker Compose. Docker Compose helps you define and manage multi-container Docker applications.
Note: Some of these steps might be optional depending on your setup. I’ll let you know when they are.
Step 1: Write Dockerfiles for Each Service
Each service needs its own Dockerfile to describe how it should be built and run. Let’s go over them!
Frontend Dockerfile (React):
# frontend/Dockerfile
FROM node:18
WORKDIR /app
COPY package.json ./
RUN npm install
COPY . .
CMD ["npm", "start"]
EXPOSE 3000
- We start with a Node image (Node 18).
- Set the working directory to
/app
. - Copy
package.json
and install dependencies. - Copy all other files and run the app.
Backend Dockerfile (Rails):
# backend/Dockerfile
FROM ruby:3.1
RUN apt-get update -qq && apt-get install -y nodejs postgresql-client
WORKDIR /app
COPY Gemfile Gemfile.lock ./
RUN bundle install
COPY . .
CMD ["rails", "server", "-b", "0.0.0.0"]
EXPOSE 3001
- Start with the Ruby image (Ruby 3.1).
- Install Node.js and PostgreSQL client (optional if you’re using PostgreSQL).
- Set the working directory and install the Ruby gems.
Elasticsearch Dockerfile:
# elasticsearch/Dockerfile
FROM docker.elastic.co/elasticsearch/elasticsearch:8.10.0
- This one’s pretty simple, just using the official Elasticsearch image.
Step 2: Create docker-compose.yml
The docker-compose.yml
file will define all the services, including their dependencies.
version: '3.9'
services:
frontend:
build:
context: ./frontend
ports:
- '3000:3000'
depends_on:
- backend # Optional: You could start frontend independently, but it might need the backend to be ready.
backend:
build:
context: ./backend
ports:
- '3001:3001'
environment:
- DATABASE_HOST=database
- ELASTICSEARCH_HOST=elasticsearch
depends_on:
- database
- elasticsearch
database:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: password
MYSQL_DATABASE: myapp
ports:
- '3306:3306'
volumes:
- db_data:/var/lib/mysql
elasticsearch:
build:
context: ./elasticsearch
ports:
- '9200:9200'
environment:
discovery.type: single-node
volumes:
db_data:
- Optional Note: Some services might not need to be connected initially, depending on what you’re testing. For example, the frontend might run fine without Elasticsearch.
Step 3: Setting Up the Environment
Before running Docker, we need to make sure our environment variables are properly configured. You can create a .env
file in the root directory to manage secrets like database passwords or API keys.
.env File Example:
DATABASE_PASSWORD=password
ELASTICSEARCH_HOST=elasticsearch
This part is optional, but keeping sensitive information out of the main codebase is a good habit to get into!
Step 4: Running Docker Compose
Now that we have everything configured, it’s time to run our stack. Simply navigate to the root directory and run:
docker-compose up --build
This command will build and start all the services as defined in the docker-compose.yml
file.
If you want to stop everything, use docker-compose down
. Easy, right?
Step 5: Access the Services
- React Frontend: Available at
http://localhost:3000
- Rails Backend API: Available at
http://localhost:3001
- Elasticsearch: Available at
http://localhost:9200
And voilà! You should see all your services running. Don’t worry if you run into issues; Docker can be a bit tricky at first. Just take a deep breath and Google any errors you see.
Conclusion
Docker helps simplify the development workflow by making it easy to run all the services you need with a single command. With this setup, you can easily scale and maintain your application, ensuring all components work seamlessly together.
Dockerizing your project not only makes it easier to manage but also helps in deploying your application across different environments with minimal changes.
And hey, don’t worry if you make mistakes! We all do. Docker takes a little getting used to, but once you get the hang of it, you’ll love it. 😊