When I use the following config in Vagrant:
Vagrant.configure("2") do |config|
config.ssh.forward_agent = true
end
While running git, I can use ssh agent forwarding on the guest with user: vagrant, but it does not work with the user: root (I get permission denied).
I need it to work with the user: root as puppet provisioning runs as root.
Is there a way to force vagrant to also allow ssh agent forwarding with the user: root?
My understanding is that it isn't possible to make a privileged vm.provision section work with SSH agent forwarding. Fundamentally, a privileged section needs to do a sudo, which breaks the link to the SSH agent.
That said, I use agent forwarding for accessing Git repos when provisioning with Puppet. I split the git and puppet commands into separate sections, privileged or not as needed:
Vagrant.configure(2) do |config|
config.vm.box = "centos/7"
config.ssh.forward_agent = true
config.vm.provision "shell", inline: <<-SHELL
yum -y update
yum install -y git
rpm -Uvh https://yum.puppet.com/puppet6-release-el-7.noarch.rpm
yum install -y puppet-agent
SHELL
config.vm.provision "shell", inline: <<-SHELL, privileged: false
mkdir -p ~/.ssh
chmod 700 ~/.ssh
# You may get failure to autenticate error messages without this.
ssh-keyscan -H github.com >> ~/.ssh/known_hosts
git clone git#github.com:group/control.git /vagrant/control
cd /vagrant/control
git checkout branch
SHELL
config.vm.provision "shell", inline: <<-SHELL
cd /vagrant/control
/opt/puppetlabs/bin/puppet apply manifest/site.pp
SHELL
end
When i'm running sudo docker-compose up inside my dir, i get this error. I'm trying to make a container, that host a php website, where you can do whoami on it.
Thanks
(13)Permission denied: AH00072: make_sock: could not bind to address 0.0.0.0:80
| no listening sockets available, shutting down
| AH00015: Unable to open logs
Dockerfile:
FROM ubuntu:16.04
RUN apt update
RUN apt install -y apache2 php libapache2-mod-php
RUN useradd -d /home/cp/ -m -s /bin/nologin cp
WORKDIR /home/cp
COPY source .
USER cp
ENTRYPOINT service apache2 start && /bin/bash
docker-compose.yml
version: '2'
services:
filebrowser:
build: .
ports:
- '8000:80'
stdin_open: true
tty: true
volumes:
- ./source:/var/www/html
- ./logs:/var/log/apache2
There's a long-standing general rule in Unix-like operating systems that only the root user can open "low" ports 0-1023. Since you're trying to run Apache on the default HTTP port 80, but you're running it as a non-root user, you're getting the "permission denied" error you see.
The absolute easiest answer here is to use a prebuilt image that has PHP and Apache preinstalled. The Docker Hub php image includes a variant of this. You can use a simpler Dockerfile:
FROM php:7.4-apache
# Has Apache, mod-php preinstalled and a correct CMD already,
# so the only thing you need to do is
COPY source /var/www/html
# If you want to run as a non-root user, you can specify
RUN useradd -r -U cp
ENV APACHE_RUN_USER cp
ENV APACHE_RUN_GROUP cp
With the matching docker-compose.yml
version: '3' # version 2 vs 3 doesn't really matter
services:
filebrowser:
build: .
ports:
- '8000:80'
volumes:
- ./logs:/var/log/apache2
If you want to build things up from scratch, the next easiest option would be the Apache User directive: have your container start as root (so it can bind to port 80) but then instruct Apache to switch to the unprivileged user once it's started up. The standard php:...-apache image has an option to do this on its own which I've shown above.
I am trying to run a React application inside a docker container. My application image was built with the following Dockerfile:
Dockerfile
FROM node:latest
LABEL autor="Ed de Almeida"
RUN apt-get update
RUN apt-get install -y apache2
RUN mkdir /tmp/myapp
COPY . /tmp/myapp
RUN cd /tmp/myapp && npm install
RUN cd /tmp/myapp && npm run build
RUN cd /tmp/myapp/build && cp -Rvf * /var/www/html
RUN cd /var/www && chown -Rvf www-data:www-data html/
EXPOSE 80
ENV APACHE_RUN_USER www-data
ENV APACHE_RUN_GROUP www-data
ENV APACHE_LOG_DIR /var/log/apache2
ENV APACHE_LOCK_DIR /var/lock/apache2
ENV APACHE_PID_FILE /var/run/apache2.pid
CMD /usr/sbin/apache2ctl -D FOREGROUND
As you may see, I create a production build, copy it to the standard directory of the Apache server and then run the Apache server. I even exposed port 80, the Apache default port.
I am creating the image with
docker build -t myimage .
and running the container with
docker run -d -p 80:80 --name myapp myimage
I am probably missing something, because I am new to Docker, because the container is there, up and running, but when I point my browser to http://localhost I got nothing.
I entered the container with
docker exec -it myapp bash
and the application is running fine inside it.
Any hints?
When running on windows, Docker will be running on a virtual machine that is running in the backgound. Thus you need to connect to this virtual machine and not to localhost.
You can get the machine ip by running:
docker-machine ip default
This will give you the IP address of the machine, which you can use to connect from the browser.
Here's my Dockerfile:
# CentOs base image
FROM centos:centos6.8
# install python, pip, apache and other packages
RUN yum -y update; yum clean all
RUN yum -y install epel-release; yum clean all
RUN yum -y install centos-release-scl; yum clean all
RUN yum -y install python27; yum clean all
RUN yum -y install python-devel.x86_64; yum clean all
RUN yum -y install python-pip; yum clean all
RUN yum -y install gcc; yum clean all
RUN yum -y install httpd httpd-devel mod_ssl; yum clean all
# Make a non root user so I can run mod_wsgi without root
# USER adm
# install Python modules needed by the Python app
COPY requirements.txt /usr/src/app/
RUN pip install --no-cache-dir -r /usr/src/app/requirements.txt
# copy files required for the app to run
COPY . /usr/src/app/
# tell the port number the container should expose
EXPOSE 80
# run the application
# CMD ["mod_wsgi", "start-server run_apache_server.wsgi"]
# CMD ["cat", "/etc/passwd"]
# CMD ["cat", "/etc/group"]
# CMD ["find", "/"]
CMD ["/bin/sh", "-c", "/usr/bin/mod_wsgi-express start-server run_apache_server.wsgi --user adm --group apache"]
I can run the app:
$ docker run -d -P --name myapp jacobirr/pleromatest
And see tcp port 80:
$ docker port myapp
80/tcp -> 0.0.0.0:32769
Here's my requirements.txt:
Flask==0.10.1
Flask-Restless==0.13.1
Flask-SQLAlchemy==0.16
Jinja2==2.7
MarkupSafe==0.18
SQLAlchemy==0.8.2
Werkzeug==0.9.2
gunicorn==17.5
itsdangerous==0.22
mimerender==0.5.4
python-dateutil==2.1
python-mimeparse==0.1.4
requests==1.2.3
six==1.3.0
wsgiref==0.1.2
setuptools==5.4.2
mod_wsgi==4.5.15
Why can't I get to localhost:32769 in the browser? I suspect this is related to:
•the user/group running apache?
•the fact that I'm installing mod_wsgi but it's nowhere on the docker "filesystem" so I have to use mod_wsgi-express?
Update:
'1' Netstat shows:
[root#9003b0d64916 app]# netstat -l
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 *:irdmi *:* LISTEN
Active UNIX domain sockets (only servers)
Proto RefCnt Flags Type State I-Node Path
unix 2 [ ACC ] STREAM LISTENING 113181 /tmp/mod_wsgi-localhost:8000:0/wsgi.1.0.1.sock
'2' httpd seems to be running in my container:
[root#9003b0d64916 mod_wsgi-localhost:8000:0]# ps aux | grep httpd
root 1 0.0 0.2 64060 5084 ? Ss 21:17 0:00 httpd (mod_wsgi-express) -f /tmp/mod_wsgi-localhost:8000:0/httpd.conf -k start -DFOREGROUND
adm 6 0.0 0.6 350928 13936 ? Sl 21:17 0:00 (wsgi:localhost:8000:0) -f /tmp/mod_wsgi-localhost:8000:0/httpd.conf -k start -DFOREGROUND
adm 7 0.0 0.1 64192 3248 ? S 21:17 0:00 httpd (mod_wsgi-express) -f /tmp/mod_wsgi-localhost:8000:0/httpd.conf -k start -DFOREGROUND
From all your outputs, your httpd / uwsgi process is definitely bound to 8000, and this is the port you need to expose on the container.
This line in netstat, is showing a bind on 8000, and nothing else.
tcp 0 0 *:irdmi *:* LISTEN
It is not obvious here, but if you use the --numeric-ports argument, it will not convert the 8000 into its known port.
In your docker file, again you should
EXPOSE 8000
When launching your container, you can also specify the port to use on the host machine:
docker run -p 8080:8000 --name ...
After this, you should be able to use your browser to hit
localhost:8080 -> container:8000
Add this to your Dockerfile, just before CMD:
WORKDIR /usr/src/app/
Assuming that your start-apache-server file is in that directory. This will help wsgi to find the needed file.
My company's development environment is based on virtual machines, running on VirtualBox. We would like to move one step further, and use the capabilities of Vagrant to have the description of the machine in a text file and then be able to "raise" that machine based on that text file. Combined to puppet, this would solve us the problem that everyone have different software versions installed in the VM.
However, Vagrant seems very focused to develop on the host, letting the machine in the background. We would need to have our development environment within the machine, so we would need a complete GUI, so when typing "vagrant up" a machine with a complete desktop environment (XFCE, KDE...) should appear.
So far, I've managed to create a "base" box from a Xubuntu distribution. But when I type "vagrant up", although the desktop appears, and I am able to login properly, Vagrant freezes at the message "Waiting for machine to boot. This may take a few minutes...". After a while Vagrant crashes due timeout. So shared folders are not created, nor the package provisioner -puppet- is executed.
How to create a virtual machine with a complete GUI using vagrant?
I just got this working with basically three steps. The advice from askubuntu.com didn't quite work for me, so try this simplified version:
Get a basic Ubuntu image working. You should be able to boot it and vagrant ssh.
Next, enable the VirtualBox display, which is off by default. Halt the VM and uncomment these lines in Vagrantfile:
config.vm.provider :virtualbox do |vb|
vb.gui = true
end
Boot the VM and observe the new display window. Now you just need to install and start xfce4. Use vagrant ssh and:
sudo apt-get install xfce4
sudo startxfce4&
If this is the first time you're running this Ubuntu environment, you'll need to run the following command before installing xfce4:
sudo apt-get update
That's it, you should be landed in a xfce4 session.
Update: For a better experience, I recommend these improvements:
Don't start the GUI as root. You really want to stay the vagrant user. To do this you need to permit anyone to start the GUI: sudo vim /etc/X11/Xwrapper.config and edit it to allowed_users=anybody.
Next, install the VirtualBox guest tools before starting the GUI. This will give you a healthy screen resolution, integrated mouse, etc.
$ sudo apt-get install -y xfce4 virtualbox-guest-dkms virtualbox-guest-utils virtualbox-guest-x11
$ sudo VBoxClient-all
Only now should you start the GUI as the vagrant user, with $ startxfce4&.
Update 2: Tried this today and the VBoxClient-all script isn't always installed. If it's missing, you can replace with the equivalent:
sudo VBoxClient --clipboard
sudo VBoxClient --draganddrop
sudo VBoxClient --display
sudo VBoxClient --checkhostversion
sudo VBoxClient --seamless
Here's Air's excellent answer in the form of a Vagrantfile
Vagrant.configure(2) do |config|
# Ubuntu 15.10
config.vm.box = "ubuntu/wily64"
config.vm.provider "virtualbox" do |vb|
# Display the VirtualBox GUI when booting the machine
vb.gui = true
end
# Install xfce and virtualbox additions
config.vm.provision "shell", inline: "sudo apt-get update"
config.vm.provision "shell", inline: "sudo apt-get install -y xfce4 virtualbox-guest-dkms virtualbox-guest-utils virtualbox-guest-x11"
# Permit anyone to start the GUI
config.vm.provision "shell", inline: "sudo sed -i 's/allowed_users=.*$/allowed_users=anybody/' /etc/X11/Xwrapper.config"
end
To start the vm
vagrant up
Login with username: vagrant, password: vagrant via the login prompt on the virtualbox GUI.
Start xfce
startx
Here is a slightly adapted Vagrantfile for Ubuntu 18.04 LTS / bionic - thanks to Air's and Nik's answers, and this post explaining how to increase the disk size when using VirtualBox (default = 10 GB).
The VM includes a LightDM login screen.
Update: I've created a GitHub repo from this example, and added many software packages for frontend + backend development.
# Optional - enlarge disk:
#vagrant plugin install vagrant-disksize
vagrant up
vagrant reload
# After reboot, the VM screen should show the LightDM login screen.
# Log in as user "vagrant", password "vagrant".
Vagrant.configure(2) do |config|
config.vm.box = "ubuntu/bionic64"
# Optional - enlarge disk (will also convert the format from VMDK to VDI):
#config.disksize.size = "50GB"
config.vm.provider "virtualbox" do |vb|
# Display the VirtualBox GUI when booting the machine
vb.gui = true
end
# https://askubuntu.com/questions/1067929/on-18-04-package-virtualbox-guest-utils-does-not-exist
config.vm.provision "shell", inline: "sudo apt-add-repository multiverse && sudo apt-get update"
# Install xfce and virtualbox additions.
# (Not sure if these packages could be helpful as well: virtualbox-guest-utils-hwe virtualbox-guest-x11-hwe)
config.vm.provision "shell", inline: "sudo apt-get install -y xfce4 virtualbox-guest-dkms virtualbox-guest-utils virtualbox-guest-x11"
# Permit anyone to start the GUI
config.vm.provision "shell", inline: "sudo sed -i 's/allowed_users=.*$/allowed_users=anybody/' /etc/X11/Xwrapper.config"
# Optional: Use LightDM login screen (-> not required to run "startx")
config.vm.provision "shell", inline: "sudo apt-get install -y lightdm lightdm-gtk-greeter"
# Optional: Install a more feature-rich applications menu
config.vm.provision "shell", inline: "sudo apt-get install -y xfce4-whiskermenu-plugin"
end
My 2 cents
Make sure you are running latest vagrant (1.3.3 now) + VirtualBox (4.2.18) to avoid bugs.
You can use shell script or inline command to install a desktop environment or a light weight window manager
For example install LXDE on top of Ubuntu 12.04 Precise base box from vagrantbox.es
Vagrant.configure("2") do |config|
# ... other configuration
config.vm.provision "shell" do |s|
s.inline = "apt-get install lubuntu-desktop -y"
end
end
If you build your own vagrant base boxes, make sure you follow the base box packaging instructions or consider tools like packer (or veewee) to automate the build.
I'm using ubuntu desktop image, it works nicely with two monitors on windows with virtual box provider.
Vagrant.configure(2) do |config|
config.vm.box = "box-cutter/ubuntu1404-desktop"
config.ssh.forward_agent = true
config.vm.network "forwarded_port", guest: 8080, host: 8080
config.vm.network "forwarded_port", guest: 3000, host: 3000
config.vm.synced_folder "../../git", "/home/vagrant/git"
config.vm.provider "virtualbox" do |vb|
vb.gui = true
vb.customize ["modifyvm", :id, "--monitorcount", "2"]
vb.memory = "2048"
end
end
You might also consider using Packer to create VirtualBox images for developers to use.
Rather than sharing the Vagrantfile which developers each use to build and run their VM, you would have a packer template (json) which is used to create a VM image. Developers download or copy the image and run it locally, directly in VB, without having to build it themselves.
Many of the publicly shared Vagrant base boxes are created with Packer.
https://askubuntu.com/questions/300799/does-ubuntu-12-04-lts-32-bit-have-graphic-user-interface/300805#300805
After installing the desktop, you'll also want to install GDM which
will let you boot directly into a graphical environment. You'll also
want to configure it.
So maybe add this?
Vagrant::Config.run do |config|
config.vm.provision :shell, :inline => "sudo apt-get install gdm"
config.vm.provision :shell, :inline => "sudo dpkg-reconfigure gdm"
end
I've patched Nik's answer a bit to avoid HTTP 404:
Vagrant.configure(2) do |config|
# Ubuntu 15.10
config.vm.box = "bento/ubuntu-18.04"
config.vm.provider "virtualbox" do |vb|
# Display the VirtualBox GUI when booting the machine
vb.gui = true
end
# Install xfce and virtualbox additions
config.vm.provision "shell", inline: "sudo apt-get update"
config.vm.provision "shell", inline: "sudo apt-get install -y xfce4 virtualbox-guest-dkms virtualbox-guest-utils virtualbox-guest-x11"
# Permit anyone to start the GUI
config.vm.provision "shell", inline: "sudo sed -i 's/allowed_users=.*$/allowed_users=anybody/' /etc/X11/Xwrapper.config"
end
Adding to billmalarky's comment above, on fedora 20 the following was necessary before starting xfce:
Install VirtualBox-guest.rpm (available from rpmfusion repos)
yum groups mark install 'graphical_environment'
yum groupinstall "Xfce"
yum install xorg-x11-drivers
Here is the code:
config.vm.provision "shell", inline: <<-SHELL
#Install Virtual Box guest additions from rpmfusion repos
cd /vagrant
yum install -y rpmfusion-free-release-20.noarch.rpm
yum install -y rpmfusion-nonfree-release-20.noarch.rpm
yum update -y
yum install -y VirtualBox-guest
#Add XFCE desktop to fedora server
yum groups mark install 'graphical_environment'
yum groupinstall -y "Xfce"
yum install -y xorg-x11-drivers
SHELL
Like the xfce4 solution by #Air. Once I had success, but today I failed with ubuntu16.04. I got this error:
xrdb can't open display 1
But luckily, I found this works:
startx
I see a few people are having problems with "startx: command not found". I had this too and it was because I was trying login and startx before the first-time provisioning had completed. Be patient, go grab a coffee. Check the original console window to see what is happening especially when the provisioning has finished.