Keycloak 8: User with username 'admin' already added - docker

I cannot start keycloak container using ansible and docker-compose. I'am getting error: User with username 'admin' already added to '/opt/jboss/keycloak/standalone/configuration/keycloak-add-user.json'
I have 3 ansible jobs:
Create netwrok:
- name: Create a internal network
docker_network:
name: internal
Setup postgres:
- name: "Install Postgres"
docker_compose:
project_name: posgressdb
restarted: true
pull: yes
definition:
version: '2'
services:
postgres:
image: postgres:12.1
container_name: postgres
restart: always
env_file:
- /etc/app/db.env
networks:
- internal
volumes:
- postgres-data:/var/lib/postgresql/data
- /etc/app/createdb.sh:/docker-entrypoint-initdb.d/init-app-db.sh
ports:
- "5432:5432"
volumes:
postgres-data:
networks:
internal:
external:
name: internal
Create keycloak container:
- name: Install keycloak
docker_compose:
project_name: appauth
restarted: true
pull: yes
definition:
version: '2'
services:
keycloak:
image: jboss/keycloak:8.0.1
container_name: keycloak
restart: always
environment:
- DB_VENDOR=POSTGRES
- DB_ADDR=postgres
- DB_PORT=5432
- DB_SCHEMA=public
- DB_DATABASE=keycloak
- DB_USER=keycloak
- DB_PASSWORD=keycloak
- KEYCLOAK_USER=admin
- KEYCLOAK_PASSWORD=admin
networks:
- internal
networks:
internal:
external:
name: internal
Does anyone have any idea why I get this error?
EDIT
If I downgrade keycloak to version 7 it starts normally!

Just to clarify the other answers. I had the same issue. What helped for me was:
stop all containers
comment out the two relevant lines
version: "3"
services:
keycloak:
image: quay.io/keycloak/keycloak:latest
environment:
# KEYCLOAK_USER: admin
# KEYCLOAK_PASSWORD: pass
...
start all containers;
wait until keycloak container has successfully started
stop all containers, again
comment back in the two lines from above
version: "3"
services:
keycloak:
image: quay.io/keycloak/keycloak:latest
environment:
KEYCLOAK_USER: admin
KEYCLOAK_PASSWORD: pass
...
start all containers
This time (and subsequent times) it worked. Keycloak was running and the admin user was registered and working as expected.

This happens when Keycloak is interrupted during boot. After this, command which attempts to add admin user starts to fail. In Keycloak 7 this wasn't fatal, but in 8.0.1 this line was added to /opt/jboss/tools/docker-entrypoint.sh which aborts the entire startup script:
set -eou pipefail
Related issue: https://issues.redhat.com/browse/KEYCLOAK-12896

The reason commenting out the KEYCLOAK_USER works is it forces a recreation of the container. The same can be accomplished with:
docker rm -f keycloak
docker compose up keycloak

I had the same issue. After commenting out the KEYCLOAK_USER env variables in docker-compose and updating the stack, the container started again.
docker_compose:
project_name: appauth
restarted: true
pull: yes
definition:
version: '2'
services:
keycloak:
image: jboss/keycloak:8.0.1
container_name: keycloak
restart: always
environment:
- DB_VENDOR=POSTGRES
- DB_ADDR=postgres
- DB_PORT=5432
- DB_SCHEMA=public
- DB_DATABASE=keycloak
- DB_USER=keycloak
- DB_PASSWORD=keycloak
#- KEYCLOAK_USER=admin
#- KEYCLOAK_PASSWORD=admin
networks:
- internal
networks:
internal:
external:
name: internal

According to my findings, the best way to set this default user is NOT by adding it via environment variables, but via the following command:
docker exec <CONTAINER> /opt/jboss/keycloak/bin/add-user-keycloak.sh -u <USERNAME> -p <PASSWORD>
As per the official documentation.

I use Keycloak 12 where I still see this problem when the startup is interrupted. I could see that removing the file "keycloak-add-user.json" and restarting the container works.
Idea is to integrate this logic into container startup. I developed a simple custom-entrypoint script.
#!/bin/bash
set -e
echo "executing the custom entry point script"
FILE=/opt/jboss/keycloak/standalone/configuration/keycloak-add-user.json
if [ -f "$FILE" ]; then
echo "keycloak-add-user.json exist, hence deleting it"
rm $FILE
fi
echo "executing the entry point script from original image"
source "/opt/jboss/tools/docker-entrypoint.sh"
And I ensured to rebuild the keycloak image with appropriate adaptations to Entrypoint
in Dockerfile during the initial deployment.
ARG DEFAULT_IMAGE_BASEURL_APPS
FROM "${DEFAULT_IMAGE_BASEURL_APPS}/jboss/keycloak:12.0.1"
COPY custom-entrypoint.sh /opt/jboss/tools/custom-entrypoint.sh
ENTRYPOINT [ "/opt/jboss/tools/custom-entrypoint.sh" ]
As our deployment is on-premise, the access to the development team is not that easy. All that our first line support could do is try giving a restart of the server where we deployed. Hence the idea of this workaround.

The way I got past this was to replace set -eou pipefail with # set -eou pipefail within the container file systems.
Logged in as root on my docker host and then edited each of the files returned by this search:
find /var/lib/docker/overlay2 | grep /opt/jboss/tools/docker-entrypoint.sh

Thomas Solutions is good but restarting all containers and start again is worthless because my docker-compose file has 7 services.
I resolved the issue in two steps.
first I commend these two lines of code like other fellows did
#- KEYCLOAK_USER=admin
#- KEYCLOAK_PASSWORD=admin
Then new terminal I run this command and it works.
docker-compose up keycloak
keycloak is a ServiceName

For other users with this problem and none of the previous answers have helped, check your connection to the database, this error usually appears if keycloak cannot connect to the database.
Test in Keycloak 8 with Docker.

I have tried the solution by
Thomas as but it sometimes works sometimes does not.
The issue is that Keycloak on boot does not find the db required, so it gets interrupted as Zmey mentions. Have you tried in the second ansible job to add depends_on: - postgres ?
Having the same issue but with docker-compose, i first started with the postgres container in order to create the necessary dbs (manual step) docker-compose up postgres and the i booted the entire setup docker-compose up.

This was happening to me when I used to shut down the Keycloak containers in Portainer and tried to get them up and running again.
I can prevent the error by also 'removing' the container after I've shut it down (both in Portainer) and then running docker-compose up. Make sure not to remove any volumes attached to your containers else you may lose data.

In case you want to add user before server start or want it look like a classic migration, build custom image with admin parameters passed
FROM quay.io/keycloak/keycloak:latest
ARG ADMIN_USERNAME
ARG ADMIN_PASSWORD
RUN /opt/jboss/keycloak/bin/add-user-keycloak.sh -u $ADMIN_USERNAME -p $ADMIN_PASSWORD
docker-compose:
auth_service:
build:
context: .
dockerfile: Dockerfile
args:
ADMIN_USERNAME: ${KEYCLOAK_USERNAME}
ADMIN_PASSWORD: ${KEYCLOAK_PASSWORD}
(do not add KEYCLOAK_USERNAME/KEYCLOAK_PASSWORD to the environment section)

I was facing this issue with Keycloak "jboss/keycloak:11.0.3" running in Docker, error:
User with username 'admin' already added to '/opt/jboss/keycloak/standalone/configuration/keycloak-add-user.json'
Adicional info, was running with PostgreSQL v13.2 also in Docker. I create some schemas for other resources but I wasn't creating the schema for the Keycloak, so the solution was for my case, run in postgres the create schema command:
CREATE SCHEMA IF NOT EXISTS keycloak AUTHORIZATION postgres;
NOTE: Hope this helps, none of other solutions shared in this post solved my issue.

You can also stop the containers and simply remove associated volumes.
If you don't know wiwh volume is associated to your keycloak container, run:
docker-compose down
for vol in $(docker volume ls --format {{.Name}}); do
docker volume rm $vol
done

Related

Cannot exec into container using GitBash when using Docker Compose

I'm new to Docker Compose, but have used Docker for years. The screen shot below is of PowerShell and of GitBash. If I run containers without docker-compose I can docker exec -it <container_ref> /bin/bash with no problems from either of these shells.
However, when running using docker-compose up both shells give no error when attempting to use docker-compose exec. They both just hang a few seconds and return to prompt.
Lastly, for some reason I do get an error in GitBash when using what I know: docker exec.... I've used this for years so I'm perplexed and posting a question. What does Docker Compose do that messes with GitBash docker ability, but not with PowerShell? And, why the hang when using docker-compose exec..., but no error?
I am using tty: true in the docker-compose.yml, but that honestly doesn't seem to make a difference. Not to throw a bunch of questions in one post, but whatever is going on could it also be the reason I can't hit my web server in the browser only when using Docker Compose to run it?
version: '3.8'
volumes:
pgdata:
external: true
services:
db:
image: postgres
container_name: trac-db
tty: true
restart: 'unless-stopped'
environment:
POSTGRES_PASSWORD: postgres
POSTGRES_USER: postgres
POSTGRES_DB: iol
volumes:
- pgdata:/var/lib/postgresql/data
network_mode: 'host'
expose:
- 5432
web:
image: lindben/trac-server
container_name: trac-server
tty: true
restart: 'unless-stopped'
environment:
ADDRESS: localhost
PORT: 3000
NODE_ENV: development
depends_on:
- db
network_mode: 'host'
privileged: true
expose:
- 1234
- 3000
```
I'm gonna be assuming you're using Docker for Desktop and so the reason you can docker exec just fine using powershell is because for windows docker is a native program\command and for GitBash which is based on bash a linux shell (bash = Bourne-Again SHell) not so much.
so when using a windows command that needs a tty you need some sort of "adapter" like winpty for example to bridge the gap between docker's interface and GitBash's one.
Here's a more detailed explanation on winpty
putting all of this aside, if trying to only use the compose options it maybe better for you to advise this question
Now, regarding your web service issue, I think that you're not actually publicly exposing your application using the expose tag. take a look at the docker-compose
expose reference. what you need is to add a "ports" tag like so as referenced here:
db:
ports:
- "5432:5432"
web:
ports:
- "1234:1234"
- "3000:3000"
Hope this solves your pickle ;)

Containerizing Cordapp with Docker Image and Docker Compose

When running Corda in docker with external Postgres DB configurations, I get insufficient privileges to access error.
Note:
Corda: 4.6 Postgresql: 9.6
Docker engine 20.10.6
Docker-compose: docker-compose version 1.29.1, build c34c88b2
docker-compose.yml file:
version: '3.3'
services:
partyadb:
hostname: partyadb
container_name: partyadb
image: "postgres:9.6"
environment:
POSTGRES_PASSWORD: postgres
POSTGRES_USER: postgres
POSTGRES_DB: partyadb
ports:
- 5432
partya:
hostname: partya
# image: corda/corda-zulu-java1.8-4.7:RELEASE
image: corda/corda-zulu-java1.8-4.6:latest
container_name: partya
ports:
- 10006
- 2223
command: /bin/bash -c "java -jar /opt/corda/bin/corda.jar run-migration-scripts -f /etc/corda/node.conf --core-schemas --app-schemas && /opt/corda/bin/run-corda"
volumes:
- ./partya/node.conf:/etc/corda/node.conf:ro
- ./partya/certificates:/opt/corda/certificates:ro
- ./partya/persistence.mv.db:/opt/corda/persistence/persistence.mv.db:rw
- ./partya/persistence.trace.db:/opt/corda/persistence/persistence.trace.db:rw
# - ./partya/logs:/opt/corda/logs:rw
- ./shared/additional-node-infos:/opt/corda/additional-node-infos:rw
- ./shared/cordapps:/opt/corda/cordapps:rw
- ./shared/drivers:/opt/corda/drivers:ro
- ./shared/network-parameters:/opt/corda/network-parameters:rw
environment:
- ACCEPT_LICENSE=${ACCEPT_LICENSE}
depends_on:
- partyadb
Error:
[ERROR] 12:41:24+0000 [main] internal.NodeStartupLogging. - Exception during node startup. Corda started with insufficient privileges to access /opt/corda/additional-node-infos/nodeInfo-5B........................................47D
The corda/corda-zulu-java1.8-4.6:latest image runs under the user corda, not root. This user has user id 1000, and also is in a group called corda, also with gid 1000:
corda#5bb6f196a682:~$ id -u corda
1000
corda#5bb6f196a682:~$ groups corda
corda : corda
corda#5bb6f196a682:~$ id -G corda
1000
The problem here seems to be that the file you are mounting into the docker container (./shared/additional-node-infos/nodeInfo-5B) does not have permissions setup in such a way as to allow this user to access it. I'm assuming the user needs read and write access. A very simple fix would be to give other read and write access to this file:
$ chmod o+rw ./shared/additional-node-infos/nodeInfo-5B
There are plenty of other ways to manage this kind of permissions issue in docker, but remember that the permissions are based on uid/gid which usually do not map nicely from your host machine into the docker container.
So the error itself describes that it's a permission problem.
I don't know if you crafted this dockerfile yourself, you may want to take a look at generating them with the dockerform task (https://docs.corda.net/docs/corda-os/4.8/generating-a-node.html#use-cordform-and-dockerform-to-create-a-set-of-local-nodes-automatically)
This permission problem could be that you're setting only read / write within the container:
- ./shared/additional-node-infos:/opt/corda/additional-node-infos:rw
or it could be that you need to change the permissions on the shared folder. Try changing the permissions of shared to 777 and see if that works, then restrict your way back down to permissions you're comfortable with.
I just configure the image to be run as root. This works but may not be safe. Simply add
services:
cordaNode:
user: root
to the service configuration.
Ref: How to configure docker-compose.yml to up a container as root

Use of docker:dind in docker-compose

So for some reason, I'd like to use a docker:dind inside a docker-compose.yml.
I know that the "easy" way is to mount directly the socket inside the image (like that : /var/run/docker.sock:/var/run/docker.sock) but I want to avoid that (for security reasons).
Here is my experimental docker-compose.yml :
version: '3.8'
services:
dind:
image: docker:19.03.7-dind
container_name: dind
restart: unless-stopped
privileged: true
environment:
- DOCKER_TLS_CERTDIR=/certs
volumes:
- dind-certs-ca:/certs/ca
- dind-certs-client:/certs/client
networks:
- net
expose:
- 2375
- 5000
volumes:
dind-certs-ca:
dind-certs-client:
networks:
net:
driver: bridge
Nothing complexe here, then I try to see if the service is correctly set :
docker logs dind
Here no problem it is up and running.
However, once I try to use it with for instance :
docker run --rm -it --network net --link dind:docker docker version
I got the following error :
Cannot connect to the Docker deamon at tcp://docker:2375. Is there a deamon running ?
Do you have any idea why the deamon is not responding ?
---------------------------------------------------------- EDIT ----------------------------------------------------------
Following hariK's comment (thanks by the way) I add the port 2376 to the exposed one. I think I'm neer solving my issue. Here is the error that I get :
error during connect: Get http://docker:2375/v1.40/version dial tcp: lookup on docker on [ip]: no such host
So I look at this error and found that it seems to be a recurrent one on dind versions (there is a lot of issues on gitlab on it like this one). There is also a post on stackoverflow on a similar issue for gitlab here.
For the workaround I tried :
Putting this value DOCKER_TLS_CERTDIR: "" hopping to turn off TLS ... but it failed
Downgrading the version to docker:18.05-dind. It actualy worked but I don't think it's a good move to make.
If someone has an idea to keep TLS ON and make it works it would be great :) (I'll still be looking on my own but if you can give a nudge with interesting links it would be cool ^^)
To use Docker with disabled TLS (i.e. TCP port 2375 by default), unset the DOCKER_TLS_CERTDIR variable in your dind service definition in Docker Compose, like:
dind:
image: docker:dind
container_name: dind
privileged: true
expose:
- 2375
environment:
- DOCKER_TLS_CERTDIR=
(NB: do not initialize it to any value like '' or "")
So I found a solution, and I added to the basic docker-compose a resgistry with TLS options.
So I had fisrt to generate the certs and then correctly mount them.
If any of you run in a similar issue I made a github repo with the docker-compose and command lines for the certs.
Some time later, and I was looking for the same thing.
Here is an example that with specific versions for the images, that should still work in a few years from now:
version: '3'
services:
docker:
image: docker:20.10.17-dind-alpine3.16
privileged: yes
volumes:
- certs:/certs
docker-client:
image: docker:20.10.17-cli
command: sh -c 'while [ 1 ]; do sleep 1; done'
environment:
DOCKER_HOST: tcp://docker:2376
DOCKER_TLS_VERIFY: 1
DOCKER_CERT_PATH: /certs/client
volumes:
- certs:/certs
volumes:
certs:
The TLS certificates are generated by the "docker" service on startup and shared using a volume.
Use the client as follows:
docker-compose exec docker-client sh
#now within docker-client container
docker run hello-world

Unable to connect mysql from docker container?

I have created a docker-compose file it has two services with Go and Mysql. It creates container for go and mysql. Now i am running code which try to connect to mysql database which is running as a docker container. but i get error.
docker-compose.yml
version: "2"
services:
app:
container_name: golang
restart: always
build: .
ports:
- "49160:8800"
links:
- "mysql"
depends_on:
- "mysql"
mysql:
image: mysql
container_name: mysql
volumes:
- dbdata:/var/lib/mysql
restart: always
environment:
- MYSQL_ROOT_PASSWORD=root
- MYSQL_DATABASE=testDB
- MYSQL_USER=root
- MYSQL_PASSWORD=root
ports:
- "3307:3306"
volumes:
dbdata:
Error while connecting to mysql database
golang | 2019/02/28 11:33:05 dial tcp 127.0.0.1:3306: connect: connection refused
golang | 2019/02/28 11:33:05 http: panic serving 172.24.0.1:49066: dial tcp 127.0.0.1:3306: connect: connection refused
golang | goroutine 19 [running]:
Connection with MySql Database
func DB() *gorm.DB {
db, err := gorm.Open("mysql", "root:root#tcp(mysql:3306)/testDB?charset=utf8&parseTime=True&loc=Local")
if err != nil {
log.Panic(err)
}
log.Println("Connection Established")
return db
}
EDIT:Updated docker file
FROM golang:latest
RUN go get -u github.com/gorilla/mux
RUN go get -u github.com/jinzhu/gorm
RUN go get -u github.com/go-sql-driver/mysql
COPY ./wait-for-it.sh .
RUN chmod +x /wait-for-it.sh
WORKDIR /go/src/app
ADD . src
EXPOSE 8800
CMD ["go", "run", "src/main.go"]
I am using gorm package which lets me connet to the database
depends_on is not a verification that MySQL is actually ready to receive connections. It will start the second container once the database container is running regardless it was ready for connections or not which could lead to such an issue with your application as it expects the database to be ready which might not be true.
Quoted from the documentation:
depends_on does not wait for db and redis to be “ready” before starting web - only until they have been started.
There are many tools/scripts that can be used to solve this issue like wait-for which sh compatible in case your image based on Alpine for example (You can use wait-for-it if you have bash in your image)
All you have to do is to add the script to your image through Dockerfile then use this command in docker-compose.yml for the service that you want to make it wait for the database.
What comes after -- is the command that you would normally use to start your application
version: "2"
services:
app:
container_name: golang
...
command: ["./wait-for", "mysql:3306", "--", "go", "run", "myapplication"]
links:
- "mysql"
depends_on:
- "mysql"
mysql:
image: mysql
...
I have removed some parts from the docker-compose for easier readability.
Modify this part go run myapplication with the CMD of your golang image.
See Controlling startup order for more on this problem and strategies for solving it.
Another issue that will rise after you solve the connection issue will be as the following:
Setting MYSQL_USER with root value will cause a failure in MySQL with this error message:
ERROR 1396 (HY000) at line 1: Operation CREATE USER failed for 'root'#'%'
This is because this user already exist in the database and it tries to create another. if you need to use the root user itself you can use only this variable MYSQL_ROOT_PASSWORD or change the value of MYSQL_USER so you can securely use it in your application instead of the root user.
Update: In case you are getting not found and the path was correct, you might need to write the command as below:
command: sh -c "./wait-for mysql:3306 -- go run myapplication"
First, if you are using latest version of docker compose you don't need the link argument in you app service. I quote the docker compose documentation Warning: The --link flag is a legacy feature of Docker. It may eventually be removed. Unless you absolutely need to continue using it, https://docs.docker.com/compose/compose-file/#links
I think the solution is to use the networks argument. This create a docker network and add each service to it.
Try this
version: "2"
services:
app:
container_name: golang
restart: always
build: .
ports:
- "49160:8800"
networks:
- my_network
depends_on:
- "mysql"
mysql:
image: mysql
container_name: mysql
volumes:
- dbdata:/var/lib/mysql
restart: always
networks:
- my_network
environment:
- MYSQL_ROOT_PASSWORD=root
- MYSQL_DATABASE=testDB
- MYSQL_USER=root
- MYSQL_PASSWORD=root
ports:
- "3307:3306"
volumes:
dbdata:
networks:
my_network:
driver: bridge
By the way, if you only connect to Mysql from your app service you don't need to expose the mysql port. If the containers runs in the same network they can reach all ports inside this network.
If my example doesn't works try this
run the docker compose and next go into the app container using
docker container exec -it CONTAINER_NAME bash
Install ping in order to test connection and then run ping mysql.

Can't set root password for OrientDB using docker-compose

I'm using the latest orientdb docker image in my docker-compose. I need to set the default root password but it's not working. My docker-compose.yml:
orientdb:
image: orientdb
ports:
- "2434:2434"
- "2480:2480"
- "2424:2424"
volumes:
- "/mnt/sda1/dockerVolumes/orientdb:/opt/orientdb/databases"
environment:
- ORIENTDB_ROOT_PASSWORD
I'm currently running:
$ export ORIENTDB_ROOT_PASSWORD=anypw
$ docker-compose up -d
You need to define password in docker-compose:
environment:
- ORIENTDB_ROOT_PASSWORD=anypw
if you want to hide your password from docker-compose you can create docker-compose:
environment:
- ORIENTDB_ROOT_PASSWORD=${ORIENTDB_ROOT_PASSWORD}
I have been able to reproduce your solution and it works:
docker-compose.yml
version: '2'
services:
orientdb:
image: orientdb
ports:
- "2434:2434"
- "2480:2480"
- "2424:2424"
environment:
- ORIENTDB_ROOT_PASSWORD=test
now:
$ docker-compose up -d
Creating network ... with the default driver
Creating test_orientdb_1
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d1f0a4a81222 orientdb "server.sh" 31 seconds ago Up 22 seconds 0.0.0.0:2424->2424/tcp, 0.0.0.0:2434->2434/tcp, 0.0.0.0:2480->2480/tcp test_orientdb_1
User: root
Pass: test
You probably tried to log in, but you have not created database.
Just create one and try to log in.
You have to first run docker-compose down command.
Then you can run the docker-compose up command.
This will remove previous configuration and allow you to connect to the database.

Resources