Internet (port 80) | v
Nginx (reverse proxy) | frontend_network v
Node.js App (port 8080, internal) | backend_network v
MySQL (port 3306, internal only)
Internet (port 80) | v
Nginx (reverse proxy) | frontend_network v
Node.js App (port 8080, internal) | backend_network v
MySQL (port 3306, internal only)
Internet (port 80) | v
Nginx (reverse proxy) | frontend_network v
Node.js App (port 8080, internal) | backend_network v
MySQL (port 3306, internal only)
MYSQL_ROOT_PASSWORD=<strong-password>
MYSQL_DATABASE=bookstore
MYSQL_USER=epicbook
MYSQL_PASSWORD=<strong-password>
NODE_ENV=production
PORT=8080
DB_HOST=db
DB_USER=epicbook
DB_PASSWORD=<strong-password>
DB_NAME=bookstore
MYSQL_ROOT_PASSWORD=<strong-password>
MYSQL_DATABASE=bookstore
MYSQL_USER=epicbook
MYSQL_PASSWORD=<strong-password>
NODE_ENV=production
PORT=8080
DB_HOST=db
DB_USER=epicbook
DB_PASSWORD=<strong-password>
DB_NAME=bookstore
MYSQL_ROOT_PASSWORD=<strong-password>
MYSQL_DATABASE=bookstore
MYSQL_USER=epicbook
MYSQL_PASSWORD=<strong-password>
NODE_ENV=production
PORT=8080
DB_HOST=db
DB_USER=epicbook
DB_PASSWORD=<strong-password>
DB_NAME=bookstore
# Stage 1 - install production dependencies
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production # Stage 2 - production runtime
FROM node:18-alpine
WORKDIR /app
COPY --from=builder /app/node_modules ./node_modules
COPY . .
EXPOSE 8080
CMD ["node", "server.js"]
# Stage 1 - install production dependencies
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production # Stage 2 - production runtime
FROM node:18-alpine
WORKDIR /app
COPY --from=builder /app/node_modules ./node_modules
COPY . .
EXPOSE 8080
CMD ["node", "server.js"]
# Stage 1 - install production dependencies
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production # Stage 2 - production runtime
FROM node:18-alpine
WORKDIR /app
COPY --from=builder /app/node_modules ./node_modules
COPY . .
EXPOSE 8080
CMD ["node", "server.js"]
upstream epicbook_app { server app:8080;
} server { listen 80; server_name _; location / { proxy_pass http://epicbook_app; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; }
}
upstream epicbook_app { server app:8080;
} server { listen 80; server_name _; location / { proxy_pass http://epicbook_app; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; }
}
upstream epicbook_app { server app:8080;
} server { listen 80; server_name _; location / { proxy_pass http://epicbook_app; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; }
}
version: '3.8' networks: frontend_network: driver: bridge backend_network: driver: bridge volumes: db_data: nginx_logs: services: db: image: mysql:8.0 networks: - backend_network healthcheck: test: ["CMD", "mysqladmin", "ping", "-h", "localhost"] interval: 10s retries: 5 start_period: 30s app: build: . depends_on: db: condition: service_healthy networks: - frontend_network - backend_network nginx: image: nginx:alpine ports: - "80:80" depends_on: app: condition: service_healthy networks: - frontend_network
version: '3.8' networks: frontend_network: driver: bridge backend_network: driver: bridge volumes: db_data: nginx_logs: services: db: image: mysql:8.0 networks: - backend_network healthcheck: test: ["CMD", "mysqladmin", "ping", "-h", "localhost"] interval: 10s retries: 5 start_period: 30s app: build: . depends_on: db: condition: service_healthy networks: - frontend_network - backend_network nginx: image: nginx:alpine ports: - "80:80" depends_on: app: condition: service_healthy networks: - frontend_network
version: '3.8' networks: frontend_network: driver: bridge backend_network: driver: bridge volumes: db_data: nginx_logs: services: db: image: mysql:8.0 networks: - backend_network healthcheck: test: ["CMD", "mysqladmin", "ping", "-h", "localhost"] interval: 10s retries: 5 start_period: 30s app: build: . depends_on: db: condition: service_healthy networks: - frontend_network - backend_network nginx: image: nginx:alpine ports: - "80:80" depends_on: app: condition: service_healthy networks: - frontend_network
docker cp db/author_seed.sql epicbook_db:/tmp/author_seed.sql
docker exec epicbook_db mysql -u epicbook -pPassword bookstore -e "source /tmp/author_seed.sql"
docker cp db/author_seed.sql epicbook_db:/tmp/author_seed.sql
docker exec epicbook_db mysql -u epicbook -pPassword bookstore -e "source /tmp/author_seed.sql"
docker cp db/author_seed.sql epicbook_db:/tmp/author_seed.sql
docker exec epicbook_db mysql -u epicbook -pPassword bookstore -e "source /tmp/author_seed.sql"
python3 -c "
content = '''..yaml content..'''
with open('docker-compose.yml', 'w') as f: f.write(content)
"
python3 -c "
content = '''..yaml content..'''
with open('docker-compose.yml', 'w') as f: f.write(content)
"
python3 -c "
content = '''..yaml content..'''
with open('docker-compose.yml', 'w') as f: f.write(content)
"
SELECT COUNT(*) FROM Book; --> 54
SELECT COUNT(*) FROM Book; --> 54
SELECT COUNT(*) FROM Book; --> 54
docker-compose down && docker-compose up -d
docker-compose down && docker-compose up -d
docker-compose down && docker-compose up -d
SELECT COUNT(*) FROM Book; --> 54
SELECT COUNT(*) FROM Book; --> 54
SELECT COUNT(*) FROM Book; --> 54