我在Compose中创建了一个mongo容器:
version: '2'
volumes:
mongodata:
driver: local
services:
mongo:
image: mongo:latest
hostname: ${MONGODB_HOST}
restart: always
ports:
- "27017:27017"
volumes:
- mongodata:/data/db
这很好用,但是现在我想在数据库上输入密码。为此,首先根据我的理解,我需要创建数据库,添加密码,然后使用--auth
标志重新启动它。我的问题是如何使用docker-compose执行此过程。
如果我在没有docker-compose的情况下做所有事情,我可以这样做。我能看到的问题包括:
a)docker-compose在docker网络中工作。
b)docker-compose在生产过程中不能在开始时运行不同的命令。
- 这很重要,因为虽然有些人说你可以在开始时运行--auth
并且它允许你第一次设置密码,但似乎并非如此。
我开始研究的一个解决方案是在运行docker-compose文件之前在我的所有服务器上运行的shell脚本:
# start the temporary container
docker run -d -v /tmp/mongodb --name tmpdb -e MONGODB_DBNAME=db_test mongo --auth
# do the user creation
docker run -it --link tmpdb --rm mongo sh -c 'mongo --host tmpdb --eval "db.createUser({ user: \"admin\", pwd: \"password\", roles: [ { role: \"root\", db: \"admin\" } ] });"'
# stop the server
docker stop tmpdb
# create new mongodb container, using the old ones data
docker run -d -p 27017:27017 --name mongo2 -e MONGODB_DBNAME=db_test mongo --auth
# clean up old container (we are using the volumes so they will stick around)
docker rm tmpdb
此文件创建一个临时容器,在其上设置用户名/密码,停止原始容器,使用旧容器创建一个新容器,并删除原始容器。新的mongo容器现在有一个密码。
所以我的结论性问题是,在docker-compose中最好的方法是什么?
我的docker-compose文件中的其他容器需要能够访问mongo所以我认为持有mongo数据的卷容器需要与docker-compose创建的网络相同
答案 0 :(得分:1)
mongo:撰写本文时的最新图片(v 3.5)接受两个环境变量,MONGO_INITDB_ROOT_USERNAME
和MONGO_INITDB_ROOT_PASSWORD
。
设置这些后,容器的入口点脚本将使用--auth启动mongod服务,然后使用提供的凭据创建管理员用户。
目前未在README
中记录这一点,但在此问题上有GitHub issue跟踪进度,并且104
脚本的docker-compose.yml
行提供了源代码
要在version: '3'
services:
mongodb:
image: mongo:3.5
hostname: ${MONGODB_HOST}
environment:
- MONGO_INITDB_ROOT_USERNAME=alice
- MONGO_INITDB_ROOT_PASSWORD=super-secret-password
restart: on-failure
ports:
- 27017:27017
volumes:
- ./mongodb:/data/db
中使用这些变量,请参阅以下代码段:
@Entity
@Table(name = "mainTable")
@Getter
@Setter
public class MainTable implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO_INCREMENT)
@Column(name = "id", nullable = false)
private Integer id;
@Embedded
DependentPK key;
@Column(name = "mainfield1")
private Integer mainField1;
}