When you self-host the server using custom ports, and a webserver is running on Ports 80 and 443, starting the server does not work. You have to stop the webserver first, start Bitwarden and then start the webserver again.
Steps to reproduce:
./bitwarden.sh start/update/restartExpected behaviour:
Bitwarden starts with no issues
Actual behaviour:
Bitwarden does not start, because Let's Encrypts Certbot tries to listen on Port 80 and 443 and fails with listen tcp 0.0.0.0:443: bind: address already in use.
Possible fix:
Let Let's Encrypt listen on the ports specified (I am not sure if that works)
Possible workaround:
Don't use Let's Encrypt, if the cert is not yet due for renewal.
At the moment, custom ports are not configurable for LE installations. Alternatively, you could edit the bitwarden.sh and bwdata/run.sh scripts to add a different port for LE to use.
I worked around it by creating a custom start/stop script that stops apache if it's running before starting the bitwarden server and then starts it again.
However, a native solution probably would be better.
#!/bin/bash
DESC="Bitwarden start/stop script"
NAME=bitwarden
SCRIPTPATH=/opt/bitwarden/bitwarden.sh
FUNCTION=$1
systemctl is-active --quiet apache2
APACHERUNNING=$?
if [ "$FUNCTION" != "stop" ] ; then
if [ $APACHERUNNING == 0 ] ; then
service apache2 stop
fi
fi
bash $SCRIPTPATH $FUNCTION
if [ "$FUNCTION" != "stop" ] ; then
if [ $APACHERUNNING == 0 ] ; then
service apache2 start
fi
fi
exit 0
I have solved this problem by changing the hardcoded port in bwdata/scripts/run.sh
There are two parts where you'd need to change the port.
The first one is in the install function:
if [ "$LETS_ENCRYPT" == "y" ]
then
echo -e -n "${CYAN}(!)${NC} Enter your email address (Let's Encrypt will send you certificate expiration reminders): "
read EMAIL
echo ""
mkdir -p $OUTPUT_DIR/letsencrypt
docker pull certbot/certbot
docker run -it --rm --name certbot -p 9090:80 -v $OUTPUT_DIR/letsencrypt:/etc/letsencrypt/ certbot/certbot \
certonly --standalone --noninteractive --agree-tos --preferred-challenges http \
--email $EMAIL -d $DOMAIN --logs-dir /etc/letsencrypt/logs
fi
and in the updateLetsEncrypt function:
function updateLetsEncrypt() {
if [ -d "${OUTPUT_DIR}/letsencrypt/live" ]
then
docker pull certbot/certbot
docker run -i --rm --name certbot -p 9191:443 -p 9090:80 \
-v $OUTPUT_DIR/letsencrypt:/etc/letsencrypt/ certbot/certbot \
renew --logs-dir /etc/letsencrypt/logs
fi
}
In this case I have exchanged ports 80 and 443 with 9090 and 9191, but you can use whatever port you want.
The advantage of doing it this way is that your webserver keeps running with no downtime, the disadvantage is that you'd need to reapply the change after an update.
I am also working on a way to change the script so the port can be chosen without going into the script itself.
This would be a good option to add before the Let's Encrypt option, so the port can be configurable from the very beginning.
Almost a year passed by and Bitwarden docker file still needs editing if you want to use it on a vps/dedi with an active web server. Quite disappointing.
You could also configure Bitwarden, with an alternate port (let's say 44300), and without Let's Encrypt (so with self-signed certificate).
Then reverse-proxy a new virtualhost of your local webserver to 127.0.0.1: 44300, and use your local Let's Encrypt instance to generate a certificate for this virtualhost.
That's the proper way to do !
Not sure then there's nothing more to do at Bitwarden side...
In addition, running Let's Encrypt on ports different than 80/443 should not work (as Let's Encrypt bot will use these ports).
I have solved this problem by changing the hardcoded port in bwdata/scripts/run.sh
There are two parts where you'd need to change the port.
The first one is in the install function:if [ "$LETS_ENCRYPT" == "y" ] then echo -e -n "${CYAN}(!)${NC} Enter your email address (Let's Encrypt will send you certificate expiration reminders): " read EMAIL echo "" mkdir -p $OUTPUT_DIR/letsencrypt docker pull certbot/certbot docker run -it --rm --name certbot -p 9090:80 -v $OUTPUT_DIR/letsencrypt:/etc/letsencrypt/ certbot/certbot \ certonly --standalone --noninteractive --agree-tos --preferred-challenges http \ --email $EMAIL -d $DOMAIN --logs-dir /etc/letsencrypt/logs fiand in the updateLetsEncrypt function:
function updateLetsEncrypt() { if [ -d "${OUTPUT_DIR}/letsencrypt/live" ] then docker pull certbot/certbot docker run -i --rm --name certbot -p 9191:443 -p 9090:80 \ -v $OUTPUT_DIR/letsencrypt:/etc/letsencrypt/ certbot/certbot \ renew --logs-dir /etc/letsencrypt/logs fi }In this case I have exchanged ports 80 and 443 with 9090 and 9191, but you can use whatever port you want.
The advantage of doing it this way is that your webserver keeps running with no downtime, the disadvantage is that you'd need to reapply the change after an update.
I am also working on a way to change the script so the port can be chosen without going into the script itself.
what should i do after i modified the run.sh file?
All I've done is rename the letsencrypt folder to letsencrypt.old, and now run.sh doesn't try to renew any certificates.
Possible fix:
Let Let's Encrypt listen on the ports specified (I am not sure if that works)
That won't work, Let's Encrypt bots will contact your server on port 80.
You then at least need port 80...
Solution in case you already have a web server is above, and is IMO the best way to go, you won't even have to restart Bitwarden anymore, you'll just have to ask Let's Encrypt / Certbot to reload your webserver to use the renewed certificates.
Most helpful comment
Almost a year passed by and Bitwarden docker file still needs editing if you want to use it on a vps/dedi with an active web server. Quite disappointing.