Dockerfile
Dockerfile¶
1. Dockerfile์ด๋?¶
Dockerfile์ Docker ์ด๋ฏธ์ง๋ฅผ ๋ง๋ค๊ธฐ ์ํ ์ค์ ํ์ผ์ ๋๋ค. ํ ์คํธ ํ์ผ์ ๋ช ๋ น์ด๋ฅผ ์์ฑํ๋ฉด Docker๊ฐ ์์๋๋ก ์คํํ์ฌ ์ด๋ฏธ์ง๋ฅผ ์์ฑํฉ๋๋ค.
Dockerfile โ docker build โ Docker Image โ docker run โ Container
(์ค๊ณ๋) (๋น๋) (ํ
ํ๋ฆฟ) (์คํ) (์ธ์คํด์ค)
์ Dockerfile์ ์ฌ์ฉํ ๊น์?¶
| ์ฅ์ | ์ค๋ช |
|---|---|
| ์ฌํ์ฑ | ๋์ผํ ์ด๋ฏธ์ง๋ฅผ ๋ฐ๋ณต ์์ฑ |
| ์๋ํ | ์๋ ์ค์ ๋ถํ์ |
| ๋ฒ์ ๊ด๋ฆฌ | Git์ผ๋ก ์ด๋ ฅ ์ถ์ |
| ๋ฌธ์ํ | ํ๊ฒฝ ์ค์ ์ด ์ฝ๋๋ก ๊ธฐ๋ก |
2. Dockerfile ๊ธฐ๋ณธ ๋ฌธ๋ฒ¶
๊ธฐ๋ณธ ๊ตฌ์กฐ¶
# ์ฃผ์
๋ช
๋ น์ด ์ธ์
์ฃผ์ ๋ช ๋ น์ด¶
| ๋ช ๋ น์ด | ์ค๋ช | ์์ |
|---|---|---|
FROM |
๋ฒ ์ด์ค ์ด๋ฏธ์ง | FROM node:18 |
WORKDIR |
์์ ๋๋ ํ ๋ฆฌ | WORKDIR /app |
COPY |
ํ์ผ ๋ณต์ฌ | COPY . . |
RUN |
๋น๋ ์ ๋ช ๋ น ์คํ | RUN npm install |
CMD |
์ปจํ ์ด๋ ์์ ๋ช ๋ น | CMD ["npm", "start"] |
EXPOSE |
ํฌํธ ๋ ธ์ถ | EXPOSE 3000 |
ENV |
ํ๊ฒฝ ๋ณ์ | ENV NODE_ENV=production |
3. ๋ช ๋ น์ด ์์ธ ์ค๋ช ¶
FROM - ๋ฒ ์ด์ค ์ด๋ฏธ์ง¶
๋ชจ๋ Dockerfile์ FROM์ผ๋ก ์์ํฉ๋๋ค.
# ๊ธฐ๋ณธ
FROM ubuntu:22.04
# Node.js ์ด๋ฏธ์ง
FROM node:18
# ๊ฒฝ๋ Alpine ์ด๋ฏธ์ง (๊ถ์ฅ)
FROM node:18-alpine
# ๋ฉํฐ ์คํ
์ด์ง ๋น๋
FROM node:18 AS builder
FROM nginx:alpine AS production
WORKDIR - ์์ ๋๋ ํ ๋ฆฌ¶
์ดํ ๋ช ๋ น์ด๊ฐ ์คํ๋ ๋๋ ํ ๋ฆฌ๋ฅผ ์ค์ ํฉ๋๋ค.
WORKDIR /app
# ์ดํ ๋ช
๋ น์ด๋ /app์์ ์คํ
COPY . . # /app์ผ๋ก ๋ณต์ฌ
RUN npm install # /app์์ ์คํ
COPY - ํ์ผ ๋ณต์ฌ¶
ํธ์คํธ์ ํ์ผ์ ์ด๋ฏธ์ง๋ก ๋ณต์ฌํฉ๋๋ค.
# ํ์ผ ๋ณต์ฌ
COPY package.json .
# ๋๋ ํ ๋ฆฌ ๋ณต์ฌ
COPY src/ ./src/
# ๋ชจ๋ ํ์ผ ๋ณต์ฌ
COPY . .
# ์ฌ๋ฌ ํ์ผ ๋ณต์ฌ
COPY package.json package-lock.json ./
ADD vs COPY¶
# COPY: ๋จ์ ๋ณต์ฌ (๊ถ์ฅ)
COPY local-file.txt /app/
# ADD: URL ๋ค์ด๋ก๋, ์์ถ ํด์ ๊ฐ๋ฅ
ADD https://example.com/file.tar.gz /app/
ADD archive.tar.gz /app/ # ์๋ ์์ถ ํด์
RUN - ๋น๋ ์ ๋ช ๋ น ์คํ¶
์ด๋ฏธ์ง ๋น๋ ์ค์ ์คํ๋ฉ๋๋ค.
# ๊ธฐ๋ณธ
RUN npm install
# ์ฌ๋ฌ ๋ช
๋ น์ด (๋ ์ด์ด ์ต์ ํ)
RUN apt-get update && \
apt-get install -y curl && \
rm -rf /var/lib/apt/lists/*
# ์บ์ ํ์ฉ์ ์ํ ๋ถ๋ฆฌ
COPY package*.json ./
RUN npm install
COPY . .
CMD - ์ปจํ ์ด๋ ์์ ๋ช ๋ น¶
์ปจํ ์ด๋๊ฐ ์์๋ ๋ ์คํ๋ฉ๋๋ค.
# exec ํ์ (๊ถ์ฅ)
CMD ["npm", "start"]
CMD ["node", "app.js"]
# shell ํ์
CMD npm start
ENTRYPOINT vs CMD¶
# ENTRYPOINT: ํญ์ ์คํ (๋ณ๊ฒฝ ์ด๋ ค์)
ENTRYPOINT ["node"]
CMD ["app.js"]
# ์คํ: node app.js
# docker run myimage other.js
# ์คํ: node other.js (CMD๋ง ๋ณ๊ฒฝ๋จ)
ENV - ํ๊ฒฝ ๋ณ์¶
# ๋จ์ผ ๋ณ์
ENV NODE_ENV=production
# ์ฌ๋ฌ ๋ณ์
ENV NODE_ENV=production \
PORT=3000 \
DB_HOST=localhost
EXPOSE - ํฌํธ ๋ฌธ์ํ¶
# ํฌํธ ๋
ธ์ถ (๋ฌธ์ ๋ชฉ์ , ์ค์ ๋งคํ์ -p ์ต์
)
EXPOSE 3000
EXPOSE 80 443
ARG - ๋น๋ ์ ๋ณ์¶
# ๋น๋ ์ ์ ๋ฌ๋ฐ๋ ๋ณ์
ARG NODE_VERSION=18
FROM node:${NODE_VERSION}
ARG APP_VERSION=1.0.0
ENV APP_VERSION=${APP_VERSION}
# ๋น๋ ์ ๊ฐ ์ ๋ฌ
docker build --build-arg NODE_VERSION=20 .
4. ์ค์ต ์์ ¶
์์ 1: Node.js ์ ํ๋ฆฌ์ผ์ด์ ¶
ํ๋ก์ ํธ ๊ตฌ์กฐ:
my-node-app/
โโโ Dockerfile
โโโ package.json
โโโ app.js
package.json:
{
"name": "my-node-app",
"version": "1.0.0",
"main": "app.js",
"scripts": {
"start": "node app.js"
},
"dependencies": {
"express": "^4.18.2"
}
}
app.js:
const express = require('express');
const app = express();
const PORT = process.env.PORT || 3000;
app.get('/', (req, res) => {
res.json({ message: 'Hello from Docker!', version: '1.0.0' });
});
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
});
Dockerfile:
# ๋ฒ ์ด์ค ์ด๋ฏธ์ง
FROM node:18-alpine
# ์์
๋๋ ํ ๋ฆฌ ์ค์
WORKDIR /app
# ์์กด์ฑ ํ์ผ ๋ณต์ฌ (์บ์ ํ์ฉ)
COPY package*.json ./
# ์์กด์ฑ ์ค์น
RUN npm install
# ์์ค ์ฝ๋ ๋ณต์ฌ
COPY . .
# ํฌํธ ๋
ธ์ถ
EXPOSE 3000
# ์คํ ๋ช
๋ น
CMD ["npm", "start"]
๋น๋ ๋ฐ ์คํ:
# ์ด๋ฏธ์ง ๋น๋
docker build -t my-node-app .
# ์ปจํ
์ด๋ ์คํ
docker run -d -p 3000:3000 --name node-app my-node-app
# ํ
์คํธ
curl http://localhost:3000
# ์ ๋ฆฌ
docker rm -f node-app
์์ 2: Python Flask ์ ํ๋ฆฌ์ผ์ด์ ¶
ํ๋ก์ ํธ ๊ตฌ์กฐ:
my-flask-app/
โโโ Dockerfile
โโโ requirements.txt
โโโ app.py
requirements.txt:
flask==3.0.0
gunicorn==21.2.0
app.py:
from flask import Flask, jsonify
app = Flask(__name__)
@app.route('/')
def hello():
return jsonify(message='Hello from Flask in Docker!')
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)
Dockerfile:
FROM python:3.11-slim
WORKDIR /app
# ์์กด์ฑ ์ค์น
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# ์์ค ๋ณต์ฌ
COPY . .
EXPOSE 5000
# Gunicorn์ผ๋ก ์คํ (ํ๋ก๋์
)
CMD ["gunicorn", "--bind", "0.0.0.0:5000", "app:app"]
๋น๋ ๋ฐ ์คํ:
docker build -t my-flask-app .
docker run -d -p 5000:5000 my-flask-app
curl http://localhost:5000
์์ 3: ์ ์ ์น์ฌ์ดํธ (Nginx)¶
ํ๋ก์ ํธ ๊ตฌ์กฐ:
my-website/
โโโ Dockerfile
โโโ nginx.conf
โโโ public/
โโโ index.html
public/index.html:
<!DOCTYPE html>
<html>
<head>
<title>My Docker Website</title>
</head>
<body>
<h1>Hello from Nginx in Docker!</h1>
</body>
</html>
Dockerfile:
FROM nginx:alpine
# ์ปค์คํ
์ค์ ๋ณต์ฌ (์ ํ์ฌํญ)
# COPY nginx.conf /etc/nginx/nginx.conf
# ์ ์ ํ์ผ ๋ณต์ฌ
COPY public/ /usr/share/nginx/html/
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
5. ๋ฉํฐ ์คํ ์ด์ง ๋น๋¶
๋น๋ ํ๊ฒฝ๊ณผ ์คํ ํ๊ฒฝ์ ๋ถ๋ฆฌํ์ฌ ์ด๋ฏธ์ง ํฌ๊ธฐ๋ฅผ ์ค์ ๋๋ค.
React ์ฑ ์์¶
# Stage 1: ๋น๋
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
# Stage 2: ์คํ (nginx๋ก ์๋น)
FROM nginx:alpine
COPY --from=builder /app/build /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
Go ์ฑ ์์¶
# Stage 1: ๋น๋
FROM golang:1.21-alpine AS builder
WORKDIR /app
COPY . .
RUN go build -o main .
# Stage 2: ์คํ (์ต์ ์ด๋ฏธ์ง)
FROM alpine:latest
WORKDIR /app
COPY --from=builder /app/main .
EXPOSE 8080
CMD ["./main"]
ํฌ๊ธฐ ๋น๊ต:
golang:1.21-alpine โ ์ฝ 300MB (๋น๋ ํ๊ฒฝ)
์ต์ข
์ด๋ฏธ์ง โ ์ฝ 15MB (์คํ ํ๊ฒฝ)
6. ๋ฒ ์คํธ ํ๋ํฐ์ค¶
.dockerignore ํ์ผ¶
๋ถํ์ํ ํ์ผ์ ๋น๋์์ ์ ์ธํฉ๋๋ค.
# .dockerignore
node_modules
npm-debug.log
.git
.gitignore
.env
*.md
Dockerfile
.dockerignore
๋ ์ด์ด ์ต์ ํ¶
# ๋์ ์: ๋งค๋ฒ ์ ์ฒด ์ฌ์ค์น
COPY . .
RUN npm install
# ์ข์ ์: package.json ๋ณ๊ฒฝ ์๋ง ์ฌ์ค์น
COPY package*.json ./
RUN npm install
COPY . .
์์ ์ด๋ฏธ์ง ์ฌ์ฉ¶
# ํฌ๊ธฐ ํผ
FROM node:18 # ~1GB
# ๊ถ์ฅ
FROM node:18-alpine # ~175MB
# ์ต์
FROM node:18-slim # ~200MB
๋ณด์¶
# ๋ฃจํธ๊ฐ ์๋ ์ฌ์ฉ์๋ก ์คํ
FROM node:18-alpine
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser
WORKDIR /app
COPY --chown=appuser:appgroup . .
7. ์ด๋ฏธ์ง ๋น๋ ๋ช ๋ น์ด¶
# ๊ธฐ๋ณธ ๋น๋
docker build -t ์ด๋ฏธ์ง๋ช
.
# ํ๊ทธ ์ง์
docker build -t myapp:1.0 .
# ๋ค๋ฅธ Dockerfile ์ฌ์ฉ
docker build -f Dockerfile.prod -t myapp:prod .
# ๋น๋ ์ธ์ ์ ๋ฌ
docker build --build-arg NODE_ENV=production -t myapp .
# ์บ์ ์์ด ๋น๋
docker build --no-cache -t myapp .
# ๋น๋ ๊ณผ์ ์์ธ ์ถ๋ ฅ
docker build --progress=plain -t myapp .
๋ช ๋ น์ด ์์ฝ¶
| Dockerfile ๋ช ๋ น์ด | ์ค๋ช |
|---|---|
FROM |
๋ฒ ์ด์ค ์ด๋ฏธ์ง ์ง์ |
WORKDIR |
์์ ๋๋ ํ ๋ฆฌ ์ค์ |
COPY |
ํ์ผ/๋๋ ํ ๋ฆฌ ๋ณต์ฌ |
RUN |
๋น๋ ์ ๋ช ๋ น ์คํ |
CMD |
์ปจํ ์ด๋ ์์ ๋ช ๋ น |
EXPOSE |
ํฌํธ ๋ฌธ์ํ |
ENV |
ํ๊ฒฝ ๋ณ์ ์ค์ |
ARG |
๋น๋ ์ ๋ณ์ |
ENTRYPOINT |
๊ณ ์ ์คํ ๋ช ๋ น |
๋ค์ ๋จ๊ณ¶
04_Docker_Compose.md์์ ์ฌ๋ฌ ์ปจํ ์ด๋๋ฅผ ํจ๊ป ๊ด๋ฆฌํ๋ ๋ฐฉ๋ฒ์ ๋ฐฐ์๋ด ์๋ค!