使用Docker使用环境变量作为入参
在使用 Docker 部署数据库时,最常见的一个问题是:
"我要怎么在启动容器时配置 PostgreSQL 的用户名、密码和数据库名称?
难道要进容器里再设置吗?"
其实完全不需要!
PostgreSQL 官方镜像已经帮我们做好了自动化初始化机制。
本文将详细讲解如何通过 环境变量、.env 文件、docker-compose.yml 等方式,
实现 PostgreSQL 的一键部署。
📘 一、官方镜像支持的环境变量
PostgreSQL 官方镜像(postgres)内置了一组可在启动时自动执行的环境变量配置项。
| 环境变量 | 作用 | 是否必需 |
|---|---|---|
| POSTGRES_USER | 初始化数据库用户名(默认:postgres) | 否 |
| POSTGRES_PASSWORD | 用户密码(⚠️ 必填) | ✅ 必需 |
| POSTGRES_DB | 启动时自动创建的数据库名 | 否 |
| POSTGRES_INITDB_ARGS | 初始化参数(如编码、区域设置) | 否 |
| PGDATA | 数据目录路径(默认 /var/lib/postgresql/data) | 否 |
💡 这些变量在第一次启动容器时生效;
若数据目录已经存在,PostgreSQL 不会重新初始化。
🧩 二、直接使用 Docker 命令启动 PostgreSQL
这是最基础的方式,通过 docker run 启动容器:
ini
docker run -d \
--name my-postgres \
-e POSTGRES_USER=myuser \
-e POSTGRES_PASSWORD=mypassword \
-e POSTGRES_DB=mydatabase \
-v /my/local/data:/var/lib/postgresql/data \
-p 5432:5432 \
postgres:16
✅ 启动后效果
-
创建用户:myuser
-
密码:mypassword
-
自动建库:mydatabase
-
数据持久化:/my/local/data
-
外部访问端口:5432
⚠️ 环境变量仅在第一次运行时初始化数据库;
后续重启容器不会重复创建用户或数据库。
🧱 三、使用 docker-compose 一键启动
推荐使用 docker-compose 管理 PostgreSQL 服务,配置更清晰、方便版本控制。
📄
docker-compose.yml
yaml
version: "3.9"
services:
postgres:
image: postgres:16
container_name: my-postgres
restart: always
environment:
POSTGRES_USER: myuser
POSTGRES_PASSWORD: mypassword
POSTGRES_DB: mydatabase
ports:
- "5432:5432"
volumes:
- ./pgdata:/var/lib/postgresql/data
启动命令:
docker-compose up -d
🔸 第一次运行时会自动创建数据库、用户和密码。
🔸 数据会持久化在 ./pgdata/ 下。
🧾 四、通过
.env
文件配置环境变量(推荐方式)
如果你不希望在 docker-compose.yml 中直接写明密码等敏感信息,
可以把它们放入 .env 文件中。
📄
.env
ini
POSTGRES_USER=myuser
POSTGRES_PASSWORD=mypassword
POSTGRES_DB=mydatabase
📄 docker-compose.yml
yaml
version: "3.9"
services:
postgres:
image: postgres:16
container_name: my-postgres
restart: always
env_file:
- .env # ✅ 写在 service 内部
ports:
- "5432:5432"
volumes:
- ./pgdata:/var/lib/postgresql/data
⚠️ 注意位置
env_file: 必须位于 service 内部,
不能写在顶层(version 同级)。
✅ 正确:
yaml
services:
postgres:
env_file:
- .env
❌ 错误:
bash
env_file: # ❌ 顶层不支持
- .env
🧩 五、多个服务共享
.env
多个容器需要共用同一组环境变量时,可以在每个服务下都引入相同的 .env 文件:
yaml
version: "3.9"
services:
postgres:
image: postgres:16
env_file:
- .env
app:
build: .
env_file:
- .env
这样 POSTGRES_USER、POSTGRES_PASSWORD 等变量会被注入到所有服务中。
🧩 六、隐式
.env
文件机制(全局替换)
Docker Compose 会自动加载当前目录下的 .env 文件,
用于替换 ${VAR_NAME} 格式的占位符,例如:
yaml
version: "3.9"
services:
postgres:
image: postgres:16
environment:
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: ${POSTGRES_DB}
这种方式不需要写 env_file:,但依赖占位符语法。
💡 推荐:
-
如果变量较多,用 env_file;
-
如果只想做模板替换,用 ${VAR_NAME}。
⚙️ 七、数据库初始化 SQL 文件
如果你希望容器首次启动时自动导入表结构或初始数据,
可以挂载 .sql 文件到 /docker-entrypoint-initdb.d/ 目录:
bash
volumes:
- ./init.sql:/docker-entrypoint-initdb.d/init.sql
PostgreSQL 会在第一次启动时自动执行该 SQL 文件。
🧩 八、验证连接是否成功
你可以通过命令行测试连接:
css
psql -h localhost -p 5432 -U myuser -d mydatabase
或者使用图形化工具(如 Navicat / DBeaver):
yaml
Host: localhost
Port: 5432
User: myuser
Password: mypassword
Database: mydatabase
🧱 九、推荐项目结构
bash
project-root/
├── docker-compose.yml
├── .env
├── pgdata/ # PostgreSQL 数据卷
└── init.sql # 初始化 SQL 文件(可选)
🧩 十、小结
| 配置项 | 推荐写法 | 说明 |
|---|---|---|
| 数据库用户名 | POSTGRES_USER | 初始化创建 |
| 数据库密码 | POSTGRES_PASSWORD | ⚠️ 必填 |
| 数据库名 | POSTGRES_DB | 自动创建 |
| 环境变量文件 | .env | 推荐集中管理 |
| 引入方式 | env_file:(service 内) | 支持多个服务共享 |
| 初始化 SQL | /docker-entrypoint-initdb.d/*.sql | 首次启动自动执行 |
✅ 总结一句话
你完全不需要进入容器配置数据库。
PostgreSQL 官方镜像通过环境变量即可完成所有初始化。
使用 env_file 可以让配置更清晰、安全,
而 Compose 则让整个数据库服务实现一键启动与持久化。
🐳 一篇教你用 Docker Compose 管理 PostgreSQL、Redis、Elasticsearch、Kafka、RabbitMQ 的全套配置指南
💡 目标:通过一份 docker-compose.yml 和 .env 文件,一键启动所有常用开发依赖。
🧭 一、目录结构推荐
bash
project-root/
├── docker-compose.yml # 主 Compose 配置
├── .env # 所有环境变量(密码、端口、版本号)
├── pgdata/ # PostgreSQL 数据卷
├── redis-data/ # Redis 持久化目录
├── es-data/ # Elasticsearch 数据卷
├── kafka-data/ # Kafka 持久化
├── rabbitmq-data/ # RabbitMQ 数据卷
└── init.sql # PostgreSQL 初始化文件(可选)
🧩 二、全局
.env
文件
.env 文件中存放所有服务的配置,Compose 会自动注入。
ini
# ====== PostgreSQL ======
POSTGRES_USER=myuser
POSTGRES_PASSWORD=mypassword
POSTGRES_DB=mydatabase
POSTGRES_PORT=5432
# ====== Redis ======
REDIS_PORT=6379
REDIS_PASSWORD=redispass
# ====== Elasticsearch ======
ELASTIC_VERSION=8.15.1
ELASTIC_PORT=9200
ELASTIC_PASSWORD=elasticpass
# ====== Kafka ======
KAFKA_BROKER_ID=1
KAFKA_PORT=9092
KAFKA_ADVERTISED_HOST_NAME=localhost
ZOOKEEPER_PORT=2181
# ====== RabbitMQ ======
RABBITMQ_USER=admin
RABBITMQ_PASSWORD=admin123
RABBITMQ_PORT=5672
RABBITMQ_UI_PORT=15672
🧱 三、docker-compose.yml 全配置模板
yaml
version: "3.9"
services:
# ======================
# PostgreSQL 数据库
# ======================
postgres:
image: postgres:16
container_name: postgres
restart: always
env_file:
- .env
ports:
- "${POSTGRES_PORT}:5432"
volumes:
- ./pgdata:/var/lib/postgresql/data
- ./init.sql:/docker-entrypoint-initdb.d/init.sql
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER}"]
interval: 10s
timeout: 5s
retries: 5
# ======================
# Redis 缓存服务
# ======================
redis:
image: redis:7
container_name: redis
restart: always
command: ["redis-server", "--requirepass", "${REDIS_PASSWORD}"]
ports:
- "${REDIS_PORT}:6379"
volumes:
- ./redis-data:/data
healthcheck:
test: ["CMD", "redis-cli", "-a", "${REDIS_PASSWORD}", "ping"]
interval: 10s
timeout: 5s
retries: 5
# ======================
# Elasticsearch 搜索引擎
# ======================
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:${ELASTIC_VERSION}
container_name: elasticsearch
restart: always
environment:
- discovery.type=single-node
- ELASTIC_PASSWORD=${ELASTIC_PASSWORD}
- ES_JAVA_OPTS=-Xms1g -Xmx1g
ports:
- "${ELASTIC_PORT}:9200"
volumes:
- ./es-data:/usr/share/elasticsearch/data
ulimits:
memlock:
soft: -1
hard: -1
healthcheck:
test: ["CMD-SHELL", "curl -u elastic:${ELASTIC_PASSWORD} -f http://localhost:9200 || exit 1"]
interval: 20s
timeout: 10s
retries: 10
# ======================
# Zookeeper(Kafka 依赖)
# ======================
zookeeper:
image: confluentinc/cp-zookeeper:7.6.1
container_name: zookeeper
restart: always
environment:
ZOOKEEPER_CLIENT_PORT: ${ZOOKEEPER_PORT}
ZOOKEEPER_TICK_TIME: 2000
ports:
- "${ZOOKEEPER_PORT}:2181"
# ======================
# Kafka 消息队列
# ======================
kafka:
image: confluentinc/cp-kafka:7.6.1
container_name: kafka
restart: always
depends_on:
- zookeeper
ports:
- "${KAFKA_PORT}:9092"
environment:
KAFKA_BROKER_ID: ${KAFKA_BROKER_ID}
KAFKA_ZOOKEEPER_CONNECT: zookeeper:${ZOOKEEPER_PORT}
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://${KAFKA_ADVERTISED_HOST_NAME}:${KAFKA_PORT}
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
volumes:
- ./kafka-data:/var/lib/kafka/data
# ======================
# RabbitMQ 消息中间件
# ======================
rabbitmq:
image: rabbitmq:3-management
container_name: rabbitmq
restart: always
environment:
RABBITMQ_DEFAULT_USER: ${RABBITMQ_USER}
RABBITMQ_DEFAULT_PASS: ${RABBITMQ_PASSWORD}
ports:
- "${RABBITMQ_PORT}:5672"
- "${RABBITMQ_UI_PORT}:15672"
volumes:
- ./rabbitmq-data:/var/lib/rabbitmq
⚙️ 四、一键启动命令
docker-compose up -d
首次启动后,会自动创建以下服务:
| 服务 | 地址 | 说明 |
|---|---|---|
| PostgreSQL | localhost:5432 | 数据库服务 |
| Redis | localhost:6379 | 缓存系统 |
| Elasticsearch | localhost:9200 | 搜索引擎接口 |
| Zookeeper | localhost:2181 | Kafka 控制器 |
| Kafka | localhost:9092 | 消息队列 |
| RabbitMQ | localhost:15672 | Web 管理后台(默认用户 admin/admin123) |
🧩 五、可选:pgAdmin、RedisInsight、Kibana 管理界面
为了方便图形化管理,可以添加这些可视化面板:
yaml
pgadmin:
image: dpage/pgadmin4
container_name: pgadmin
restart: always
environment:
PGADMIN_DEFAULT_EMAIL: admin@local.com
PGADMIN_DEFAULT_PASSWORD: admin
ports:
- "8080:80"
depends_on:
- postgres
redisinsight:
image: redis/redisinsight:latest
container_name: redisinsight
restart: always
ports:
- "8001:8001"
depends_on:
- redis
kibana:
image: docker.elastic.co/kibana/kibana:${ELASTIC_VERSION}
container_name: kibana
restart: always
environment:
- ELASTICSEARCH_HOSTS=http://elasticsearch:9200
- ELASTICSEARCH_USERNAME=elastic
- ELASTICSEARCH_PASSWORD=${ELASTIC_PASSWORD}
ports:
- "5601:5601"
depends_on:
- elasticsearch
🧠 六、统一配置策略总结
| 服务 | 配置方式 | 初始化说明 |
|---|---|---|
| PostgreSQL | POSTGRES_USER, POSTGRES_PASSWORD, POSTGRES_DB | 自动建库与建用户 |
| Redis | 命令行参数 --requirepass | 无需 SQL 初始化 |
| Elasticsearch | 环境变量 + 数据卷 | 自动单节点启动 |
| Kafka | KAFKA_ADVERTISED_LISTENERS + Zookeeper | 自动创建主题存储 |
| RabbitMQ | RABBITMQ_DEFAULT_USER, RABBITMQ_DEFAULT_PASS | 自带管理 UI |
| 所有服务 | env_file: .env | 可集中配置 |
🧩 七、开发环境建议
- 每个服务挂载本地数据目录(防止容器删除后丢失数据)
- .env 中集中管理所有密码、端口、版本
- 不要在容器内部改配置,统一通过 docker-compose.yml
- 启动顺序自动处理(depends_on)
🧱 八、启动与调试命令
bash
# 启动全部服务
docker-compose up -d
# 查看运行状态
docker ps
# 查看某个服务日志
docker-compose logs -f postgres
docker-compose logs -f redis
# 停止全部
docker-compose down
🚀 九、总结
✅ 你不需要进入任何容器;
✅ 所有配置都在 .env 中完成;
✅ docker-compose up -d 一键启动整个后端服务栈。
Docker Compose 已经成为现代开发环境的标准做法,它的好处是:
- 快速重建开发环境;
- 一键启动全部依赖;
- 支持持久化数据;
- 可无缝迁移到服务器。
📦 十、可扩展服务建议
未来如果要加入:
| 服务 | 说明 |
|---|---|
| MinIO | 自建 S3 对象存储 |
| Nginx | 网关 / 静态资源托管 |
| MongoDB | NoSQL 文档型数据库 |
| ClickHouse | 分析型数据库 |
| Grafana + Prometheus | 监控系统 |
都可以直接加在这个 docker-compose.yml 里。