Reputation: 5109
I have a docker-compose with a service I'd love to launch several times with various env variables. The idea is to launch the service several times, notably on a series of ports.
My current strategy is to copy and paste the service name N times, N being the number of time I need to launch the service, but that seems very unefficient.
Reproducible example:
app/app.js
var http = require('http');
var name = process.env.NAME || "Jack"
var port = process.env.PORT || 1234
var server = http.createServer(function(req, res) {
res.writeHead(200);
res.end(`Hi ${name}!`);
});
server.listen(port, () => console.log(`Running on port ${port}`));
app/Dockerfile
FROM node:10
WORKDIR /usr/src/app
COPY . .
CMD [ "node", "app.js" ]
docker-compose.yml
version: '2'
services:
node:
build: app
environment:
- NAME=${NAME}
- PORT=${PORT}
command: node app.js
expose:
- "${PORT}"
ports:
- "${PORT}:${PORT}"
What I want to do is to be able to do :
NAME=joe PORT=1234 docker-compose up -d node
NAME=jack PORT=1235 docker-compose up -d node
And I now have two services, one on each port. localhost:1234 show "hello joe", localhost:1235 "Hello jack". Right now if I do that the same service is relaunched.
Things I have tried so far:
--scale
options, unfortunately I couldn't find how to control the env var settingscontainer_name
entry in the service definition. Unfortunately it seems that it's still the same service launched and renamedUpvotes: 4
Views: 1406
Reputation: 11
https://docs.docker.com/compose/environment-variables/
As you can see the mentioned link you need to create you need to have a .env file at the same level as your compose file .
Now to run your same compose file multiple time without changing the parameters manually create a sample file say sample_file with your env variable as key value like "Key1=value_1" "key2=value_2" Now use sed to replace value_1 and value_2 and create a new file with .env and pipe the command with docker compose up -d
"sed -i -e 's/value_1/1234/g' -e 's/value_2/Joe/g' sample_file>sample_file.env|docker-compose up -d node"
Upvotes: 0
Reputation: 158976
If you can launch all of the containers in the same docker-compose.yml
file then you can trim down a couple of options to make the amount of syntax more palatable.
There's no specific requirement that the process inside a container listen on the same port that's being published on the host, and in modern Docker expose:
means almost nothing. That means you don't specifically need to configure a PORT
environment variable; you can always start the container process on its default port 1234 and just remap that per-container. You also don't need to repeat the default CMD
from the Dockerfile.
So an all-in-one Docker Compose setup for what you show could look like
version: '3' # 2 vs. 3 doesn't really matter here
services:
joe:
build: app
environment:
- NAME=joe
ports: '1234:1234'
jack:
build: app
environment:
- NAME=jack
ports: '1235:1234'
If you want to use a series of docker-compose
invocations as you've shown, Compose has an internal notion of a "project", and it keeps track of the state of the containers in a project. By default the current directory's local name is used as the project name. In your docker-compose up
command, Compose sees that you've changed the port mapping and environment settings for the node
container in the same single project, so it replaces the existing container.
To tell Compose that there are different projects, you need the docker-compose -p
option
NAME=joe PORT=1234 docker-compose -p joe up -d node
NAME=jack PORT=1235 docker-compose -p jack up -d node
Note that you will need to repeat this option on every docker-compose
command invocation. If you use non-Compose commands like docker ps
you will be able to see the project name included as part of the container name (joe_node_1
, jack_node_1
).
Upvotes: 1