├── .env-dist ├── .gitignore ├── README.md ├── config-dev.php ├── data ├── Dockerfile ├── README.md ├── medium-dataset.sql.gz └── phplist-entrypoint.sh ├── phplist-dev.yml ├── phplist.yml ├── phplist ├── Dockerfile ├── Dockerfile.git ├── Dockerfile.php5 ├── build.sh ├── docker-apache-phplist.conf ├── docker-entrypoint.sh ├── docker-phplist-config-dev.php ├── docker-phplist-config-live.php └── phplist-crontab ├── proxy ├── Dockerfile ├── apache-proxy-start.sh └── proxy.conf ├── resetdb.sh ├── setup.sh ├── start-phplist.sh ├── stop-phplist.sh └── tail-maillog.sh /.env-dist: -------------------------------------------------------------------------------- 1 | MYSQL_ROOT_PASSWORD="somerootpassword" 2 | MYSQL_DATABASE=phplistdb 3 | MYSQL_USER=phplist 4 | MYSQL_PASSWORD=phplist 5 | PHPLIST_ADMINNAME="Your Name" 6 | PHPLIST_ADMINPASSWORD="SomeRandomPassword" 7 | PHPLIST_ADMINEMAIL=YourEmail@Yourdomain.com 8 | PHPLIST_VERSION=latest 9 | PORT=8000 10 | HOSTNAME=localhost 11 | # make sure these are world writable 12 | IMAGES=/path/to/images 13 | PLUGINS=/path/to/plugins 14 | FORCE_STOP_ALL_BEFORE=false -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .env 2 | .idea/ 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # phplist-docker 2 | 3 | Run [phpList](www.phplist.org) in a Docker environment 4 | 5 | Work in progress, more features coming. The current configuration will not send any emails to the world. All emails will be delivered to the mailhog container locally. 6 | 7 | **Please note** this is a place to experiment with phpList and Docker and primarily for making development easier. The actual docker images are built in the [main phpList repository](https://github.com/phpList/phplist3/blob/main/Dockerfile.release) with a [Github action](https://github.com/phpList/phplist3/blob/main/.github/workflows/build-release.yml) when it is tagged for release. 8 | 9 | If you want to contribute to the live docker builds, create a pull request there. 10 | 11 | You can add "feature requests" to the issue list here though. Then it can be created here and once working well ported to the main repository. 12 | 13 | The main aim of this setup is to facilitate phpList development. If you are looking for 14 | phpList in Docker, without the need to make any changes, you can find it on [Docker Hub](https://hub.docker.com/repository/docker/phplist/phplist_) 15 | 16 | ## pre-requisites 17 | 18 | To use this you need to have a working docker environment. 19 | Head over to https://www.docker.com to get started 20 | 21 | You need the following commands (I'm reporting the versions I have, Jan 2022) 22 | 23 | docker 24 | 25 | $ docker --version 26 | Docker version 20.10.12, build e91ed57 27 | 28 | docker-compose 29 | 30 | $ docker-compose --version 31 | docker-compose version 1.29.0, build unknown 32 | 33 | ## configuration 34 | 35 | Copy the .env-dist file and save it as .env in your current folder 36 | 37 | cp .env-dist .env 38 | 39 | Edit the values to match your situation 40 | 41 | You can leave the database values, but you will need to set 42 | 43 | PHPLIST_ADMINNAME="Your Name" 44 | PHPLIST_ADMINPASSWORD="SomeRandomPassword" 45 | PHPLIST_ADMINEMAIL=YourEmail@Yourdomain.com 46 | 47 | and 48 | 49 | PORT=8000 50 | HOSTNAME=localhost 51 | 52 | *HOSTNAME* is the name you will be accessing your phpList installation on. Port will be 53 | the port to connect to. To try it out on your local machine, you can use the defaults. 54 | 55 | ## installation 56 | 57 | Once you have set the values in .env, you can run 58 | 59 | ./start-phplist.sh 60 | 61 | This will choose between two possible scenarios. 62 | - phpList running from the code in the containers (phplist.yml) 63 | - phpList running from the code on your local machine (phplist-dev.yml) 64 | 65 | For the latter, you need to map the code on your machine to the code in the container. You can do this with variables in the .env file. 66 | 67 | Wait some time, because the first time the database will be created and configured. 68 | 69 | Once it's all set up, you will be able to login to phpList on the HOSTNAME and PORT 70 | you specified in the .env file using "admin" as the login and the PHPLIST_ADMINPASSWORD 71 | you set in the .env file as the password. 72 | 73 | In the above example, that means you point your browser at 74 | 75 | http://localhost:8000/lists/admin/ 76 | 77 | and login with username "admin" and password "SomeRandomPassword" 78 | 79 | 80 | ## images and plugins 81 | 82 | You can map the images and plugins folders to a folder on the host machine with 83 | 84 | IMAGES=/path/to/images 85 | PLUGINS=/path/to/plugins 86 | 87 | When you do that, they will be retained when you rebuild the system. Make sure the folders are fully world-writable (hint: chmod 777) 88 | 89 | When these variables are absent, the images and plugins will be placed on Docker Volumes. 90 | 91 | ## config 92 | 93 | There are a few config settings you can put in the environment, but probably the easiest way to control the phpList configuration is to map your config file as a volume. 94 | 95 | Something like 96 | 97 | vi php 98 | 99 | 100 | ## features 101 | 102 | Current features in the container are: 103 | 104 | - CKEditor Plugin 105 | - Image Upload works (and will be saved when you stop the container) 106 | - All emails will be sent to Mailhog, which you can get to with http://localhost:8025 107 | 108 | ## hints 109 | 110 | * For docker-compose, visit https://github.com/docker/compose/releases 111 | * For docker, visit https://github.com/moby/moby/releases 112 | * You can choose the version of phpList to run with the PHPLIST_VERSION variable in .env 113 | 114 | To reset the admin password run 115 | 116 | ``docker exec phplist_dbhost mysql -u[DBUSER] -p[DBPASS] [DBNAME] -e 'update phplist_admin set password = "NEWPASSWORD"'`` 117 | 118 | 119 | ## development. 120 | 121 | To use this docker setup for development of phpList, phpList themes or phpList plugins visit https://resources.phplist.com/develop/docker 122 | 123 | Here is a [quick script](https://github.com/phpList/phplist-docker/blob/master/setup.sh) to show how to set up a development environment. 124 | 125 | 126 | ## database 127 | 128 | * To reset the database run 129 | 130 | ```docker system prune -f 131 | docker volume rm phplist-docker_dbhost_data 132 | ``` 133 | 134 | and then restart phpList-docker 135 | 136 | * To load your own data into the database, take a DB snapshot, eg "phplist.sql.gz" and run 137 | 138 | ```gunzip -c phplist.sql.gz | docker exec -i phplist_dbhost mysql mysql -u[DBUSER] -p[DBPASS] [DBNAME]``` -------------------------------------------------------------------------------- /config-dev.php: -------------------------------------------------------------------------------- 1 | 5 | RUN apt-get update && apt-get upgrade -y 6 | 7 | RUN apt-get install -y apt-utils \ 8 | vim apache2 net-tools php5-mysql \ 9 | libapache2-mod-php5 php5-curl php5-gd \ 10 | git cron php5-imap 11 | 12 | RUN cd /var/www/ && \ 13 | git clone https://github.com/phplist/phplist3.git phpList3 && \ 14 | cd phpList3/public_html/lists && \ 15 | rm -f texts && git clone https://github.com/phpList/phplist-lan-texts.git texts && \ 16 | cd admin/ && rm -f help && git clone https://github.com/phpList/phplist-lan-help.git help && \ 17 | rm -f info && git clone https://github.com/phpList/phplist-lan-info.git info && \ 18 | cd ui && \ 19 | git clone https://github.com/phplist/phplist-ui-dressprow.git dressprow && \ 20 | git clone https://github.com/phpList/phplist-ui-bootlist.git 21 | 22 | RUN cd /tmp && git clone https://github.com/bramley/phplist-plugin-ckeditor.git && \ 23 | mv phplist-plugin-ckeditor/plugins/* /var/www/phpList3/public_html/lists/admin/plugins/ && \ 24 | rm -rf phplist-plugin-ckeditor 25 | 26 | RUN rm -f /etc/apache2/sites-enabled/000-default.conf && \ 27 | cd /var/www/ && find . -type d -name .git -print0 | xargs -0 rm -rf && \ 28 | find . -type d -print0 | xargs -0 chmod 755 && \ 29 | find . -type f -print0 | xargs -0 chmod 644 && \ 30 | mkdir /var/www/phpList3/public_html/images && \ 31 | chmod 777 /var/www/phpList3/public_html/images && \ 32 | chmod 777 /var/www/phpList3/public_html/lists/admin/plugins 33 | 34 | ARG REFRESH=unknown 35 | RUN echo REFRESH=${REFRESH} 36 | 37 | COPY docker-apache-phplist.conf /etc/apache2/sites-enabled/ 38 | COPY docker-phplist-config.php /var/www/phpList3/config.php 39 | COPY phplist-crontab / 40 | RUN crontab /phplist-crontab 41 | COPY docker-entrypoint.sh /usr/local/bin/ 42 | 43 | #RUN chmod 755 /usr/bin/phplist 44 | #RUN /usr/bin/phplist -pinitialise 45 | 46 | EXPOSE 80 443 47 | 48 | VOLUME ["/var/www", "/var/log/apache2", "/etc/apache2"] 49 | #CMD ["/bin/bash"] 50 | #CMD ["/usr/sbin/apache2ctl", "-D", "FOREGROUND"] 51 | ENTRYPOINT ["docker-entrypoint.sh"] 52 | -------------------------------------------------------------------------------- /phplist/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | VERSION=$1 4 | 5 | cd "$(dirname "$0")" 6 | . .env 7 | 8 | if [[ -f $VERSIONDIR/phplist-${VERSION}.tgz ]]; then 9 | docker rmi -f phplist/phplist:$VERSION 10 | docker system prune -f 11 | tar zxf $VERSIONDIR/phplist-${VERSION}.tgz 12 | docker build --build-arg VERSION=$VERSION --no-cache -f Dockerfile -t phplist/phplist:$VERSION . 13 | docker push phplist/phplist:$VERSION 14 | rm -rf phplist-${VERSION} 15 | else 16 | docker rmi -f phplist/phplist:latest 17 | docker build --no-cache -f Dockerfile.git -t phplist/phplist:latest . 18 | docker push phplist/phplist:latest 19 | fi 20 | -------------------------------------------------------------------------------- /phplist/docker-apache-phplist.conf: -------------------------------------------------------------------------------- 1 | ServerName phplist.docker 2 | 3 | ServerAdmin webmaster@localhost 4 | DocumentRoot /var/www/phpList3/public_html/ 5 | SetEnv ConfigFile /etc/phplist/config.php 6 | DirectoryIndex index.php 7 | php_value upload_max_filesize 50M 8 | php_value post_max_size 100M 9 | 10 | 11 | AllowOverride All 12 | 13 | 14 | -------------------------------------------------------------------------------- /phplist/docker-entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ## entry point file, needed to be able to pass ENV vars from docker-compose.yml to the containers. 4 | 5 | echo Initialising phpList, Please wait 6 | 7 | exec 6>&1 8 | exec > /usr/bin/phplist 9 | 10 | echo '#!/bin/bash' 11 | echo -n 12 | echo 'exec 6>&1' 13 | echo 'exec > /dev/null 2>&1' 14 | printenv | sed 's/^\(.*\)$/export \1/g' 15 | echo -n 16 | echo 'exec 1>&6 6>&-' 17 | echo /usr/bin/php /var/www/phpList3/public_html/lists/admin/index.php -c /var/www/phpList3/config.php \$\* 18 | 19 | exec 1>&6 6>&- 20 | chmod 755 /usr/bin/phplist 21 | 22 | ## wait for the DB container, but not forever 23 | UNCONNECTED=$(phplist | grep "Cannot connect") 24 | COUNT=1 25 | while [[ "$UNCONNECTED" ]] && [[ $COUNT -lt 11 ]] ; do 26 | echo Waiting for the Database to be available - $COUNT/10 27 | sleep 10; 28 | UNCONNECTED=$(phplist | grep "Cannot connect") 29 | COUNT=$(( $COUNT + 1 )) 30 | done 31 | 32 | if [[ "$UNCONNECTED" ]]; then 33 | echo Failed to find a Database to connect to 34 | exit; 35 | fi 36 | 37 | /usr/bin/phplist -pinitialise 38 | /usr/bin/phplist -pinitlanguages 39 | 40 | echo READY 41 | echo $(phplist --version) 42 | service cron start 43 | /usr/sbin/apache2ctl -D FOREGROUND 44 | -------------------------------------------------------------------------------- /phplist/docker-phplist-config-dev.php: -------------------------------------------------------------------------------- 1 | > /var/log/phplist.log 2>&1 2 | 0 3 * * * root phplist -pprocessbounces >> /var/log/phplist-bounces.log 2>&1 3 | -------------------------------------------------------------------------------- /proxy/Dockerfile: -------------------------------------------------------------------------------- 1 | 2 | #Choose Debian 3 | FROM debian:latest 4 | #MAINTAINER DiouxX "github@diouxx.be" 5 | #https://hub.docker.com/r/diouxx/apache-proxy/ 6 | #Don't ask questions during install 7 | ENV DEBIAN_FRONTEND noninteractive 8 | 9 | #Install apache2 and enable proxy mode 10 | 11 | RUN apt update \ 12 | && apt -y install \ 13 | apache2 \ 14 | nano 15 | RUN a2enmod proxy \ 16 | && a2enmod proxy_http \ 17 | && service apache2 stop 18 | #Ports 19 | EXPOSE 80 443 20 | #Volumes 21 | #VOLUME /opt/proxy-conf 22 | #Launch Apache2 on FOREGROUND 23 | 24 | COPY proxy.conf /opt/proxy-conf/ 25 | 26 | COPY apache-proxy-start.sh /opt/ 27 | RUN chmod +x /opt/apache-proxy-start.sh 28 | ENTRYPOINT ["/opt/apache-proxy-start.sh"] -------------------------------------------------------------------------------- /proxy/apache-proxy-start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | #Copy virtualhost on apache directory 4 | cp /opt/proxy-conf/*.conf /etc/apache2/sites-available/ 5 | 6 | #List site and enable 7 | ls /etc/apache2/sites-available/ -1A | a2ensite *.conf 8 | 9 | # Apache gets grumpy about PID files pre-existing 10 | rm -f /var/run/apache2/apache2.pid 11 | 12 | #Launch Apache on Foreground 13 | /usr/sbin/apache2ctl -D FOREGROUND 14 | -------------------------------------------------------------------------------- /proxy/proxy.conf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ServerName phplist-dev.docker.phplist.com 5 | ProxyPass / http://phplist-dev/ 6 | ProxyPassReverse / http://phplist-dev/ 7 | 8 | 9 | 10 | 11 | 12 | ServerName phplist-test.docker.phplist.com 13 | ProxyPass / http://phplist-hosted/ 14 | ProxyPassReverse / http://phplist-hosted/ 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /resetdb.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cid=$(docker ps |grep testdata | cut -d ' ' -f 1) 4 | docker exec -it $cid mysqladmin -uphplist -pphplist drop -f phplistdb 5 | docker exec -it $cid mysqladmin -uphplist -pphplist create phplistdb 6 | 7 | 8 | -------------------------------------------------------------------------------- /setup.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ## This script will create a folder called "phplist-dev" 4 | ## and check out various repositories in there. 5 | ## after that it will initialise the Docker setup and start it 6 | ## 7 | 8 | rm -rf phplist-dev 9 | [[ -d phplist-dev ]] && { 10 | echo Error removing previous folder, please remove manually and try again 11 | exit; 12 | } 13 | mkdir phplist-dev 14 | cd phplist-dev 15 | git clone https://github.com/phplist/phplist3 16 | mkdir phpListPlugins 17 | mkdir phpListThemes 18 | 19 | cd phpListThemes 20 | git clone https://github.com/phpList/phplist-ui-bootlist.git 21 | cd .. 22 | cd phpListPlugins 23 | 24 | ## add here any other plugins that you want to check out 25 | ## below is the full list of plugins from 26 | ## https://resources.phplist.com/plugins/start 27 | 28 | git clone https://github.com/bramley/phplist-plugin-addons.git 29 | git clone https://github.com/bramley/phplist-plugin-amazonses.git 30 | git clone https://github.com/michield/phplist-plugin-attributeselect.git 31 | git clone https://github.com/bramley/phplist-plugin-autoresponder.git 32 | git clone https://github.com/bramley/phplist-plugin-botbouncer.git 33 | git clone https://github.com/bramley/phplist-plugin-bounces.git 34 | git clone https://github.com/michield/phplist-plugin-campaignslicer.git 35 | git clone https://github.com/bramley/phplist-plugin-statistics.git 36 | git clone https://github.com/bramley/phplist-plugin-campaigns.git 37 | git clone https://github.com/bramley/phplist-plugin-captcha.git 38 | git clone https://github.com/bramley/phplist-plugin-ckeditor.git 39 | git clone https://github.com/bramley/phplist-plugin-common.git 40 | git clone https://github.com/arnoldle/phplist-plugin-conditionalPlaceholderPlugin.git 41 | git clone https://github.com/bramley/phplist-plugin-contentareas.git 42 | git clone https://github.com/bradallenfisher/phplist-plugin-cosign.git 43 | git clone https://github.com/urapoh/phplist-plugin-customheader.git 44 | git clone https://github.com/michield/phplist-plugin-dateplaceholder.git 45 | git clone https://github.com/michield/phplist-plugin-domainthrottlemap.git 46 | git clone https://github.com/michield/phplist-plugin-embedremoteimages.git 47 | git clone https://github.com/michield/phplist-plugin-fckeditor.git 48 | git clone https://github.com/bramley/phplist-plugin-hcaptcha.git 49 | git clone https://github.com/bramley/phplist-plugin-housekeeping.git 50 | git clone https://github.com/bramley/phplist-plugin-imap.git 51 | git clone https://github.com/arnoldle/phplist-plugin-inlineImagePlugin.git 52 | git clone https://github.com/phpList/phplist-plugin-invite.git 53 | git clone https://github.com/michield/phplist-plugin-listcleaner.git 54 | git clone https://github.com/arnoldle/phplist-plugin-listNamePrefixPlugin.git 55 | git clone https://github.com/bramley/phplist-plugin-mailgun.git 56 | git clone https://github.com/bramley/phplist-plugin-attachment.git 57 | git clone https://github.com/phpList/phplist-plugin-disposablemailblock.git 58 | git clone https://github.com/bramley/phplist-plugin-recaptcha.git 59 | git clone https://github.com/bramley/phplist-plugin-recaptchav3.git 60 | git clone https://github.com/phpList/phplist-plugin-restapi.git 61 | git clone https://github.com/bramley/phplist-plugin-rssfeed.git 62 | git clone https://github.com/michield/phplist-plugin-rssmanager.git 63 | git clone https://github.com/bramley/phplist-plugin-segment.git 64 | git clone https://github.com/bramley/phplist-plugin-sendgrid.git 65 | git clone https://github.com/bramley/phplist-plugin-smtp2go.git 66 | git clone https://github.com/arnoldle/phplist-plugin-subjectLinePlaceholdersPlugin.git 67 | git clone https://github.com/arnoldle/phplist-plugin-subjectPrefixPlugin.git 68 | git clone https://github.com/bramley/phplist-plugin-subscribers.git 69 | git clone https://github.com/bramley/phplist-plugin-timezone.git 70 | git clone https://github.com/bramley/phplist-plugin-tinymce.git 71 | git clone https://github.com/bramley/phplist-plugin-viewbrowser.git 72 | git clone https://github.com/michield/phplist-plugin-subscribeexample.git 73 | git clone https://github.com/phpList/phplist-plugin-simplesaml.git 74 | git clone https://github.com/michield/phplist-plugin-develop.git 75 | 76 | cd .. 77 | git clone https://github.com/phpList/phplist-docker.git 78 | cp phplist-docker/.env-dist phplist-docker/.env 79 | echo >> phplist-docker/.env 80 | echo CODE_PATH=$(pwd)/phplist3/ >> phplist-docker/.env 81 | echo THEME_DEV_PATH=$(pwd)/phpListThemes >> phplist-docker/.env 82 | echo PLUGIN_DEV_PATH=$(pwd)/phpListPlugins >> phplist-docker/.env 83 | cp phplist-docker/config-dev.php phplist3/config.php 84 | 85 | cd phplist-docker 86 | docker-compose -f phplist-dev.yml up 87 | 88 | -------------------------------------------------------------------------------- /start-phplist.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cd $(dirname $0) 4 | 5 | FILE=${1:-phplist.yml} 6 | 7 | # Sourcing the configuration file. 8 | # NOTE One can override default compose file here 9 | . .env 10 | 11 | # Check if any of the DEV settings are found 12 | if [[ -n $THEME_DEV_PATH ]] && [[ -n $CODE_PATH ]] && [[ -n $PLUGIN_DEV_PATH ]]; then 13 | FILE=phplist-dev.yml 14 | echo Using the DEV version 15 | fi 16 | 17 | if [[ $FORCE_STOP_ALL_BEFORE =~ (y(es)?|true|1) ]]; then 18 | docker stop $(docker ps -q) 19 | fi 20 | 21 | docker-compose -f $FILE down --remove-orphans 22 | docker-compose -f $FILE pull 23 | docker-compose -f $FILE up -d --build -V 24 | -------------------------------------------------------------------------------- /stop-phplist.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cd $(dirname $0) 4 | 5 | FILE=${1:-phplist.yml} 6 | 7 | # Sourcing the configuration file. 8 | # NOTE One can override default compose file here 9 | . .env 10 | 11 | if [[ -n $THEME_DEV_PATH ]] && [[ -n $CODE_PATH ]] && [[ -n $PLUGIN_DEV_PATH ]]; then 12 | FILE=phplist-dev.yml 13 | echo Using the DEV version 14 | fi 15 | 16 | docker-compose -f $FILE down 17 | -------------------------------------------------------------------------------- /tail-maillog.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ## this script will find the postfix container and 4 | ## show the output of the mail log file 5 | 6 | PFC=$(docker ps -q -f 'ancestor=phplist/postfix') 7 | 8 | [ "$PFC" ] && \ 9 | docker exec $(docker ps -q -f 'ancestor=phplist/postfix') tail -f /var/log/mail.log 10 | --------------------------------------------------------------------------------