In my Dockerfile, I create a user, "alice" (generic name that isn't industry-specific) with a home directory. Alice has /home/.bashrc and root has /root/.bashrc (which all users can read - chmod a+r /root/bashrc).
I can run docker compose exec app /bin/bash and access the app container's command line as the root user. I can then su alice and have full access to the container as Alice.
However, if I run docker compose exec --user alice app /bin/bash, I get "bash: /root/.bashrc: Permission denied" followed by the "alice#sha:working/directory" cli prompt. ls ~/ gives the error: "ls: cannot open directory '/root/': Permission denied".
My docker-compose.yml file (abridged):
services:
app:
build:
context: ./docker/app
dockerfile: Dockerfile
args:
- HOST_GID=${HOST_GID}
- HOST_UID=${HOST_UID}
volumes:
${full_source_path}:/var/www/html
...
env_file: .env
My Dockerfile (abridged):
FROM --platform=$BUILDPLATFORM php:7.1-apache
# Set up Apache
RUN a2enmod rewrite
# UID & GID are passed in to use the same UID/GID as the host user's user account
ARG HOST_UID
ARG HOST_GID
RUN echo "Creating alice" && \
groupadd \
--force \
--gid ${HOST_GID} \
alice && \
sync && \
useradd \
--no-log-init \
--uid ${HOST_UID} \
--gid ${HOST_GID} \
--create-home \
--shell /bin/bash \
alice \
&& \
sync && \
echo "DONE"
# copy externally created files, including .bashrc, into /home/alice/
...
RUN chmod a+r /root/.bashrc
RUN chmod a+r /home/alice/.bashrc
RUN echo "Finalizing" && \
chown -R alice:alice /home/alice/ && \
echo "DONE"
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
# Persist cached writes
RUN sync
WORKDIR /var/www/html
ENTRYPOINT ["/entrypoint.sh"]
My entrypoint.sh file:
#!/usr/bin/env bash
set -e
echo "Starting Apache"
exec apache2-foreground
echo "Container Ready"
sleep infinity
My host:
MacOS 12.4
Docker Desktop 4.10.1
Related
I am mounting a local file inside a docker container through the docker-compose.yml file:
version: '3'
services:
myapp:
build:
context: ./dockerfiles
dockerfile: myapp.Dockerfile
args:
- UID=1000
- GID=1000
network_mode: host
volumes:
- ./volumes/logs:/opt/myapp/logs
The mounted folder belongs to my user(uid: 1000, gid:1000) and these are the ids that the docker user gets, but the docker user cannot write to the mounted folder (permission denied).
Dockerfile:
FROM centos:7
ARG UID=1000
ARG GID=1000
RUN yum -y update && \
yum -y install epel-release && \
yum -y install passwd curl jq supervisor iputils openssl-devel
RUN yum -y clean all
RUN useradd -m -s /bin/sh user && \
passwd -d user && \
usermod -o -u ${UID} user && \
groupmod -o -g ${GID} user
VOLUME ["/opt/myapp/logs"]
ADD myapp /opt/myapp/app
ADD supervisor/services.ini /etc/supervisord.d/services.ini
ADD start.sh /
RUN chown -R user:user /opt/myapp
RUN chown user:user /start.sh
USER user
CMD ["/start.sh"]
start.sh
exec supervisord -c /etc/supervisord.conf -n
service.ini
[program:myapp]
user = user
autorestart = true
stdout_logfile = /dev/stdout
stdout_logfile_maxbytes = 0
stderr_logfile = /dev/stderr
stderr_logfile_maxbytes = 0
command = /opt/myapp/app
My app is run with user and it cannot write it's logs in the mounted folder.
My goal is to access the logs from outside the docker container.
Even if I run with the root user inside the container, I still cannot access the mounted folder!
I'm trying to run a Flask app with Celery (worker + beat) on Docker Alpine using docker-compose.
I want it to run with a non-root user celery in my Docker container.
The flask app is building ok and works, but my celery containers are failing with this error:
File "/usr/lib/python3.6/site-packages/celery/platforms.py", line 543, in maybe_drop_privileges
_setuid(uid, gid)
File "/usr/lib/python3.6/site-packages/celery/platforms.py", line 564, in _setuid
initgroups(uid, gid)
File "/usr/lib/python3.6/site-packages/celery/platforms.py", line 507, in initgroups
return os.initgroups(username, gid)
PermissionError: [Errno 1] Operation not permitted
My Dockerfile:
I tried to add RUN chown celery:celery /etc/group thinking that was the issue but it's still failing
FROM alpine:3.8
RUN apk update && \
apk add build-base python3 python3-dev libffi-dev libressl-dev && \
cd /usr/bin && \
ln -sf python3 python && \
ln -sf pip3 pip && \
pip install --upgrade pip
COPY requirements.txt .
RUN pip install -r requirements.txt
RUN addgroup celery
RUN adduser celery -G celery -s /bin/sh -D
RUN mkdir -p /var/log/celery/ && chown celery:celery /var/log/celery/
RUN mkdir -p /var/run/celery/ && chown celery:celery /var/run/celery/
RUN chown celery:celery /etc/group # added to try fixing the issue
USER celery
ENV FLASK_APP=flask_app
WORKDIR app/
COPY flask_app flask_app
My docker-compose:
(...)
celeryworker:
build: .
command: celery -A flask_app.tasks worker --loglevel=INFO --uid=celery --pidfile=/tmp/celeryworker-shhh.pid
celerybeat:
build: .
command: celery -A flask_app.tasks beat --loglevel=INFO --uid=celery --pidfile=/tmp/celerybeat-shhh.pid
You should do like that
RUN mkdir -p /var/log/celery/ /var/run/celery/
RUN useradd -G root celery && \
chgrp -Rf root /var/log/celery/ /var/run/celery/ && \
chmod -Rf g+w /var/log/celery/ /var/run/celery/c && \
chmod g+w /etc/passwd
...
RUN chmod a+x /start.sh
USER celery
ENTRYPOINT ["/start.sh"]
You should create user celery firsts. Then, add this user into group root. After that you need set write permission for this folder you need to put logs and /etc/passwd.
You also need to have one script to add your user into /etc/passwd
#!/bin/bash
#
if [ `id -u` -ge 10000 ]; then
echo "celery:x:`id -u`:`id -g`:,,,:/home/web:/bin/bash" >> /etc/passwd
fi
Both answers from #Shashank V and #Kine were really relevant and helpful but still had some issues afterward.
After doing some research, I finally made it works with the following configuration
Dockerfile
FROM alpine:3.11.0
RUN apk update && \
apk add build-base python3 python3-dev libffi-dev libressl-dev && \
ln -sf /usr/bin/python3 /usr/bin/python && \
ln -sf /usr/bin/pip3 usr/bin/pip && \
pip install --upgrade pip
RUN mkdir -p /var/log/celery/ /var/run/celery/
RUN addgroup app && \
adduser --disabled-password --gecos "" --ingroup app --no-create-home app && \
chown app:app /var/run/celery/ && \
chown app:app /var/log/celery/
USER app
ENV PATH="/home/app/.local/bin:${PATH}"
WORKDIR app/
COPY requirements.txt .
RUN pip install --user -r requirements.txt\
COPY flask_app flask_app
ENV FLASK_APP=flask_app
docker-compose
(...)
celeryworker:
build: .
command: >
celery -A shhh.tasks worker
--loglevel=INFO
--logfile=/var/log/celery/celeryworker-shhh.log
--pidfile=/var/run/celery/celeryworker-shhh.pid
celerybeat:
build: .
command: >
celery -A shhh.tasks beat
--loglevel=INFO
--logfile=/var/log/celery/celerybeat-shhh.log
--pidfile=/var/run/celery/celerybeat-shhh.pid
--schedule=/var/run/celery/celerybeat-schedule # specify schedule db in a loc where app has read/write access
You have to be root user if you want to use --uid or --gid argument. Try removing these arguments.
I'm trying to create a Jenkins Docker agent that has Go.
The following is my Dockerfile.
After I build it, if I try: docker run myimage:0.0.1 go version returns the Go version, however if I try this, it doesn't find Go at all.
docker run --privileged --dns 9.0.128.50 --dns 9.0.130.50 -d -P --name slave myimage:0.0.1
docker ps ## grab the port number
ssh -p PORT_NUMBER jenkins#localhost
What am I missing in order to make Go available under the Jenkins user?
FROM golang:1.11.5-alpine
RUN apk add --no-cache \
bash \
curl \
wget \
git \
openssh \
tar
COPY ssh/*key /etc/ssh/
COPY skel/ /home/jenkins
COPY id_rsa /home/jenkins/.ssh/id_rsa
COPY id_rsa.pub /home/jenkins/.ssh/id_rsa.pub
RUN addgroup docker \
&& adduser -s /bin/bash -h /home/jenkins -G docker -D jenkins \
&& echo "jenkins ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers \
&& echo "jenkins:jenkinspass" | chpasswd \
&& chmod u+s /bin/ping \
&& chown -R jenkins:docker /home/jenkins \
&& mv /etc/profile.d/color_prompt /etc/profile.d/color_prompt.sh \
&& mv /bin/sh /bin/sh.bak \
&& ln -s /bin/bash /bin/sh
# Standard SSH port
EXPOSE 22
CMD ["/usr/sbin/sshd", "-D"]
If you run:
docker run myimage:0.0.1 which go
You will see that go executable in path /usr/local/go/bin/go
If you connect as jenkins user via ssh and run /usr/local/go/bin/go version all work as well.
Conclusion:
Go installation provided as root user
jenkins user added after go installed and haven't /usr/local/go/bin/go in his $PATH environment variable.
Solution:
Add /usr/local/go/bin/go to $PATH for user jenkins
Use go executable with full path.
I am unable to switch user to a non-root user from the entry point script. The User directive to change the user in Dockerfile works, but I am not able to change permissions using chmod. To overcome this issue I created entrypoint.sh script to change the folder permissions but when I try to switch user using su command, it apparently doesn't work, the container is still running as root.
The Dockerfile
FROM php:7.2-fpm
# Installing dependencies
RUN apt-get update && apt-get install -y \
build-essential \
mysql-client \
libpng-dev \
libjpeg62-turbo-dev \
libfreetype6-dev \
locales \
zip \
jpegoptim optipng pngquant gifsicle \
vim \
unzip \
git \
curl
# Installing composer
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
ENV USER_ID=1000
ENV GROUP_ID=1000
ENV USER_NAME=www
ENV GROUP_NAME=www
RUN groupadd -g $GROUP_ID $GROUP_NAME
RUN useradd -u $USER_ID -ms /bin/bash -g $GROUP_NAME $USER_NAME
RUN mkdir /app
WORKDIR /app
EXPOSE 9000
COPY ./entrypoint.sh /
RUN ["chmod", "+x", "/entrypoint.sh"]
ENTRYPOINT ["/entrypoint.sh"]
Entrypoint.sh file
#!/bin/bash
if [ -n "$USER_ID" -a -n "$GROUP_ID" ]; then
chown -R $USER_NAME:$GROUP_NAME .
su $USER_NAME
fi
php-fpm
exec "$#"
whatever I do I am not able to switch user from the entrypoint.sh script.
My case is to run the container as non-root user.
I think that your su command should be something like
su $USERNAME --command "/doit.sh"
b/c your entrpoiny script is switching user, doing nothing, and then switching back to root.
To solve this you need to change your dockerfile and add:
RUN echo "root ALL = NOPASSWD: /bin/su ALL" >> /etc/sudoers
Or use gosu what is better:
# install gosu
# seealso:
# https://docs.docker.com/develop/develop-images/dockerfile_best-practices/
# https://github.com/tianon/gosu/blob/master/INSTALL.md
# https://github.com/tianon/gosu
RUN set -eux; \
apt-get update; \
apt-get install -y gosu; \
rm -rf /var/lib/apt/lists/*; \
# verify that the binary works
gosu nobody true
Then inside entrypoint.sh:
gosu root yourservice &
#ie: gosu root /usr/sbin/sshd -D &
exec gosu no-root-user yourservice2
# ie: exec gosu no-root-user tail -f /dev/null
My docker-compose is the same as the default one, exepting that it has this additional code:
hyperledger:
build:
context: .
ports:
- 8081:8081
My Dockerfile:
FROM hyperledger/composer-cli:0.19.0
WORKDIR /app
COPY . /app
USER root
RUN chown -R composer:composer .
USER composer
RUN ls -la
# RUN composer archive create -t dir -n .
RUN rm -rf .stage && mkdir ./.stage
RUN echo '{"name": "hyper-discover-network","x-type": "hlfv1","x-commitTimeout": 300,"version": "1.0.0","client": {"organization": "Org1","connection": {"timeout": {"peer": {"endorser": "300","eventHub": "300","eventReg": "300"},"orderer": "300"}}},"channels": {"composerchannel": {"orderers": ["orderer.example.com"],"peers": {"peer0.org1.example.com": {}}}},"organizations": {"Org1": {"mspid": "Org1MSP","peers": ["peer0.org1.example.com"],"certificateAuthorities": ["ca.org1.example.com"]}},"orderers": {"orderer.example.com": {"url": "grpc://orderer.example.com:7050"}},"peers": {"peer0.org1.example.com": {"url": "grpc://peer0.org1.example.com:7051","eventUrl": "grpc://peer0.org1.example.com:7053"}},"certificateAuthorities": {"ca.org1.example.com": {"url": "http://ca.org1.example.com:7054","caName": "ca.org1.example.com"}}}' > connection.json
EXPOSE 8081
USER root
RUN chmod 777 docker-entrypoint.sh
COPY docker-entrypoint.sh /usr/local/bin/
RUN ln -s usr/local/bin/docker-entrypoint.sh / # backwards compat
ENTRYPOINT [ "sh", "/app/docker-entrypoint.sh" ]
CMD [ "composer" ]
And my docker-entrypoint.sh:
#!/bin/bash
# set -e
if [ "$1" = 'composer' ]; then
composer archive create -t dir -n .
echo '{...}' > connection.json
composer card create -p ./connection.json -u PeerAdmin -r PeerAdmin -r ChannelAdmin -f .stage/PeerAdmin.card \
-c crypto-config/peerOrganizations/org1.example.com/ca/ca.org1.example.com-cert.pem \
-k crypto-config/peerOrganizations/org1.example.com/ca/19ab65abbb04807dad12e4c0a9aaa6649e70868e3abd0217a322d89e47e1a6ae_sk
# composer-playground
composer card import -f .stage/PeerAdmin.card && composer card list && ls -la && pwd
echo 'som shit'
composer network install -a hyper-discover-network#0.0.1.bna -c PeerAdmin#hyper-discover-network
fi
The error appears at composer network install ... line.
I am building this environment by executing: ./startFabric.sh && docker-compose up hyperledger