├── .gitignore ├── README.md ├── config └── .gitignore ├── data ├── config.yml.in.dist ├── init.properties.in.dist ├── tigase.conf.dist └── trusted.pem.dist ├── docker-compose.yml ├── httpupload ├── Dockerfile ├── README.md ├── entrypoint.sh └── install-httpupload.sh ├── kontalk-setup ├── launcher ├── letsencrypt └── post-hook.sh ├── local.properties.dist ├── mysql └── my.cnf └── tigase ├── Dockerfile ├── README.md ├── apt_preferences ├── entrypoint.sh ├── install-jkyotocabinet.sh └── post-install.sh /.gitignore: -------------------------------------------------------------------------------- 1 | local.properties 2 | .version 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Kontalk server for Docker 2 | ========================= 3 | 4 | Here you may find a few scripts and files to build a Kontalk container 5 | (actually 3 containers) for running a Kontalk server. 6 | 7 | ## Requirements 8 | 9 | * Recent 64-bit Linux distro (we suggest Debian) 10 | * Docker 11 | * Docker Compose 12 | * git 13 | 14 | ## Setting up environment 15 | 16 | Setup a new user account (or use an existing one, root is not needed and not recommended) 17 | on a system with Docker installed and enabled. The user account should be part of the docker 18 | group so it will be able to use Docker. 19 | 20 | Clone this repository in any location (we recommend the home directory of your user account): 21 | 22 | ```bash 23 | git clone https://github.com/kontalk/xmppserver-docker.git kontalk-server 24 | cd kontalk-server 25 | ``` 26 | 27 | ## Configure the containers 28 | 29 | A setup script can be used to generate a local configuration: 30 | 31 | ```bash 32 | ./kontalk-setup 33 | ``` 34 | 35 | Answer all questions or skip them by pressing enter: the default value will be used (unless specified otherwise). 36 | 37 | ``` 38 | Please give a name to your new Kontalk server instance. 39 | Kontalk instance name [prime]: 40 | 41 | Kontalk is available in the following branches: 42 | master: bleeding-edge, latest modifications. Possibly unstable. Use for development only. 43 | staging: used in Kontalk test server. It should have the latest features with a certain degree of stability. 44 | production: used in Kontalk production server. Stable and tested. 45 | You can also specify a version tag. 46 | 47 | Kontalk version/branch to build [staging]: 48 | XMPP service name [prime.kontalk.net]: 49 | XMPP plain listen port [5222]: 50 | XMPP secure listen port [5223]: 51 | XMPP s2s listen port [5269]: 52 | MySQL root password [root]: 53 | MySQL kontalk password [kontalk]: 54 | MySQL time zone [Europe/Rome]: 55 | 56 | The HTTP file upload service is used by clients to upload and download media. 57 | It should be exposed directly or better through a reverse proxy (e.g. Nginx). 58 | We will ask you for the listen port exposed to the host system and the URLs seen by clients. 59 | Note that those URLs should be available from the outside, i.e. from the Internet 60 | 61 | HTTP file upload service listen port [8828]: 62 | HTTP file upload URL [https://10.0.2.2:8828/]: 63 | HTTP file download URL [https://10.0.2.2:8828/]: 64 | Max HTTP upload file size [20971520]: 65 | 66 | You can now build the images by running ./launcher bootstrap 67 | ``` 68 | 69 | A file called `local.properties` will be created. Please note that any modification 70 | to this file will require a rebuild ([see below](#upgraderebuild-the-containers)). 71 | If all went ok, you can now do the bootstrap: 72 | 73 | ```bash 74 | ./launcher bootstrap 75 | ``` 76 | 77 | This should take some time: it will build the images and setup the containers. 78 | 79 | At this point, if you want to just run a development server for tests, just 80 | go straight below to [the actual startup](#start-the-containers). 81 | 82 | ## Setting up the server 83 | 84 | A more serious environment will require prior creation of a SSL certificate and 85 | a GPG key for the server. For the containers to use them, certificate and keys must 86 | be located in: 87 | 88 | * `config/server-private.key`: GPG server private key (**must not be password-protected!**) 89 | * `config/server-public.key`: GPG server public key 90 | * `config/privatekey.pem`: SSL private key 91 | * `config/certificate.pem`: SSL certificate 92 | * `config/cachain.pem`: SSL certificate authorities chain (optional) 93 | 94 | Your setup will also surely include some tweaking on the server configuration. 95 | You can edit the default configuration file `config/init.properties.in`. 96 | The local server tutorial can be used to configure some of the parameters, 97 | e.g. [registration providers](//github.com/kontalk/tigase-kontalk/blob/master/docs/local-server-howto.md#registration) or 98 | [push notifications](//github.com/kontalk/tigase-kontalk/blob/master/docs/local-server-howto.md#push-notifications). A quick 99 | reference to Tigase parameters can be found [here](http://docs.tigase.org/tigase-server/7.1.0/Properties_Guide/html/), 100 | while the administration guide is [here](http://docs.tigase.org/tigase-server/7.1.0/Administration_Guide/html/). 101 | We strongly recommend giving it a look to know if the default configuration suits your needs. 102 | 103 | > When configuring Tigase init.properties.in file, leave placeholders for 104 | variables untouched (e.g. `{{ .Env.FINGERPRINT }}`): they will be replaced 105 | automatically. 106 | 107 | Another file to look into would be `config/tigase.conf`. Some environment variables are defined, 108 | you should especially check JAVA\_OPTIONS which contains the JVM parameters (heap memory, GC parameters, etc.). 109 | Note that despite the extension, it's a simple shell script file sourced by the server startup script, 110 | so bash syntax applies. 111 | 112 | ### Trust store for outgoing SSL connection 113 | 114 | You can use a custom trust store for outgoing SSL connections (e.g. from registration or push providers). The launcher 115 | script will produce one automatically for you. Just create a directory called `trustedcerts` and put one certificate 116 | per file in there. Be sure the files end in `.cer`. Then update JAVA\_OPTIONS in `config/tigase.conf` and add this at the end: 117 | 118 | ``` 119 | -Djavax.net.ssl.trustStore=truststore -Djavax.net.ssl.trustStorePassword=truststore 120 | ``` 121 | 122 | ## Start the containers 123 | 124 | Run this command: 125 | 126 | ```bash 127 | ./launcher start 128 | ``` 129 | 130 | The script will start 3 containers in the background: 131 | 132 | * **xmpp**: the actual [Tigase XMPP server](http://tigase.net/content/tigase-xmpp-server) 133 | * **db**: MySQL database server 134 | * **httpupload**: the HTTP upload component needed to upload media (pictures, audio files, etc.) 135 | 136 | The actual container names will be prefixed with the instance name given to `kontalk-setup`. 137 | For example, if you typed "prime" as the instance name, containers will be called prime\_xmpp, prime\_db, prime\_httpupload. 138 | 139 | The instance name can be changed in local.properties (INSTANCE\_NAME), but before doing that you 140 | must destroy the old containers (`./launcher destroy`), alter INSTANCE\_NAME and then run `./launcher bootstrap`. 141 | 142 | The launcher script has some other useful commands that can be used. You can see 143 | a quick help by launching it without any arguments. 144 | 145 | ## Upgrade/rebuild the containers 146 | 147 | You must rebuild the containers if you: 148 | 149 | * modified local.properties (run `./launcher rebuild`) 150 | * want to upgrade the Kontalk server (meaning modifying the VERSION property in local.properties) 151 | 152 | You don't need to rebuild if you modify `config/init.properties.in`, but you will need to restart it: 153 | 154 | ```bash 155 | ./launcher restart 156 | ``` 157 | 158 | ## Help and support 159 | 160 | You can ask for further information on how to deploy a Kontalk server and share your experiences on our community forum: 161 | https://forum.kontalk.org/c/support/server 162 | -------------------------------------------------------------------------------- /config/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /data/config.yml.in.dist: -------------------------------------------------------------------------------- 1 | component_jid: media.{{ .Env.XMPP_SERVICE }} 2 | component_secret: secret 3 | component_host: xmpp 4 | component_port: 5270 5 | 6 | storage_path : ../disk 7 | 8 | whitelist: 9 | - {{ .Env.XMPP_SERVICE }} 10 | max_file_size: {{ .Env.HTTPUPLOAD_MAX_SIZE }} 11 | 12 | http_address: 0.0.0.0 13 | http_port: 8828 14 | #http_keyfile: server.key 15 | #http_certfile: server.crt 16 | 17 | get_url : {{ .Env.HTTPUPLOAD_GET_URL }} 18 | put_url : {{ .Env.HTTPUPLOAD_PUT_URL }} 19 | 20 | expire_interval: 82800 #time in secs between expiry runs (82800 secs = 23 hours). set to '0' to disable 21 | expire_maxage: 2592000 #files older than this (in secs) get deleted by expiry runs (2592000 = 30 days) 22 | user_quota_hard: 104857600 #100MiB. set to '0' to disable rejection on uploads over hard quota 23 | user_quota_soft: 78643200 #75MiB. set to '0' to disable deletion of old uploads over soft quota an expiry runs 24 | allow_web_clients: true #answer OPTIONS requests to allow web clients to upload files 25 | -------------------------------------------------------------------------------- /data/init.properties.in.dist: -------------------------------------------------------------------------------- 1 | # Default Kontalk configuration, fine for most configurations 2 | 3 | # XMPP host where you're serving your Kontalk instance 4 | # Kontalk extensions support one virtual host only for now 5 | sess-man/plugins-conf/urn\:ietf\:params\:xml\:ns\:xmpp-sasl/host={{ .Env.XMPP_SERVICE }} 6 | # Virtual hosts served by this instance (must match the above) 7 | --virt-hosts={{ .Env.XMPP_SERVICE }} 8 | # Administrator JID (must be in the above domain) 9 | --admins=admin@{{ .Env.XMPP_SERVICE }} 10 | 11 | # Fingerprint of the GPG server key 12 | sess-man/plugins-conf/fingerprint={{ .Env.FINGERPRINT }} 13 | 14 | # The global network domain (do not change this if you want to participate in the Kontalk global network) 15 | sess-man/plugins-conf/network-domain=kontalk.net 16 | sess-man/plugins-conf/service-terms-url=https://kontalk.github.io/network/privacy 17 | 18 | # Database configuration (the two db-uri parameters must be identical) 19 | --user-db=mysql 20 | --user-db-uri=jdbc:mysql://db:3306/{{ .Env.MYSQL_DATABASE }}?user={{ .Env.MYSQL_USER }}&password={{ urlquery .Env.MYSQL_PASSWORD }}&useUnicode=true&characterEncoding=UTF-8&serverTimezone={{ urlquery .Env.MYSQL_TIMEZONE }} 21 | sess-man/plugins-conf/db-uri=jdbc:mysql://db:3306/{{ .Env.MYSQL_DATABASE }}?user={{ .Env.MYSQL_USER }}&password={{ urlquery .Env.MYSQL_PASSWORD }}&useUnicode=true&characterEncoding=UTF-8&serverTimezone={{ urlquery .Env.MYSQL_TIMEZONE }} 22 | pubsub/pubsub-repo-url=jdbc:mysql://db:3306/{{ .Env.MYSQL_DATABASE }}?user={{ .Env.MYSQL_USER }}&password={{ urlquery .Env.MYSQL_PASSWORD }}&useUnicode=true&characterEncoding=UTF-8&serverTimezone={{ urlquery .Env.MYSQL_TIMEZONE }} 23 | 24 | # Registration provider configuration 25 | # Dummy provider configuration 26 | # It will always accept 123456 as a valid verification code 27 | # Good for a remote test server 28 | sess-man/plugins-conf/kontalk\:jabber\:iq\:register/providers[s]=dummy=org.kontalk.xmppserver.registration.DummyProvider 29 | sess-man/plugins-conf/kontalk\:jabber\:iq\:register/dummy-sender=123456 30 | 31 | # security features to enable - leave empty to disable all 32 | sess-man/plugins-conf/kontalk\:jabber\:iq\:register/security[s]=throttling-ip,throttling-phone,throttling-prefix 33 | 34 | # IP-based throttling: delay in seconds 35 | sess-man/plugins-conf/kontalk\:jabber\:iq\:register/throttling-ip.delay[I]=30 36 | # IP-based throttling: max attempts before triggering throttling 37 | sess-man/plugins-conf/kontalk\:jabber\:iq\:register/throttling-ip.trigger-attempts[I]=3 38 | 39 | # phone-based throttling: delay in seconds 40 | sess-man/plugins-conf/kontalk\:jabber\:iq\:register/throttling-phone.delay[I]=30 41 | # phone-based throttling: max attempts before triggering throttling 42 | sess-man/plugins-conf/kontalk\:jabber\:iq\:register/throttling-phone.trigger-attempts[I]=3 43 | 44 | # prefix-based throttling: delay in seconds 45 | sess-man/plugins-conf/kontalk\:jabber\:iq\:register/throttling-prefix.delay[I]=30 46 | # prefix-based throttling: max attempts before triggering throttling 47 | sess-man/plugins-conf/kontalk\:jabber\:iq\:register/throttling-prefix.trigger-attempts[I]=3 48 | # prefix-based throttling: most significant digits to consider (excluding the plus sign) 49 | sess-man/plugins-conf/kontalk\:jabber\:iq\:register/throttling-prefix.length[I]=6 50 | 51 | # Endpoints configuration 52 | # All endpoints must declare a clientCertCA pointing to a valid certificate chain file 53 | # (any CA chain will do, it won't actually be used but Tigase won't work without it) 54 | 55 | # Client endpoint configuration 56 | --c2s-ports=5222,5223 57 | c2s/connections/5223/socket=ssl 58 | c2s/clientCertCA=trusted.pem 59 | 60 | # Websocket endpoint configuration 61 | message-router/components/msg-receivers/ws2s.active[B]=false 62 | ws2s/connections/5290/socket=ssl 63 | ws2s/clientCertCA=trusted.pem 64 | 65 | # BOSH endpoint configuration 66 | message-router/components/msg-receivers/bosh.active[B]=false 67 | bosh/connections/5280/socket=ssl 68 | bosh/clientCertCA=trusted.pem 69 | 70 | # S2S endpoint configuration (comment to disable XMPP federation) 71 | --s2s-ports=5269 72 | 73 | # Enabled plugins, comma-separated 74 | # prefixed with a minus (-) means not loaded, prefixed with nothing or with a plus (+) means loaded. 75 | # add "+kontalk:push:legacy" to enable Kontalk push notifications (external component must also be configured below) 76 | --sm-plugins=-amp,-message-carbons,-jabber:iq:auth,-jabber:iq:register,-jabber:iq:privacy,-jabber:iq:last,-msgoffline,-urn:xmpp:blocking,-urn:xmpp:csi:0,+message,+msgoffline2,+presence:urn:xmpp:pubkey:2,+kontalk:jabber:iq:register,+kontalk:jabber:iq:roster,+urn:xmpp:pubkey:2,+kontalk:urn:xmpp:blocking,+kontalk:urn:xmpp:csi:0,+kontalk:jabber:iq:last,+pep 77 | 78 | # Comment these to revert to default logging 79 | --debug=server,xmpp.impl 80 | --debug-packages=org.kontalk 81 | 82 | # External components. Do not change the default names! 83 | # --comp-xxx parameter pairs follow a numbering order 84 | # whenever you delete/comment or insert a component, remember to fix the numbering!! 85 | 86 | # Network component 87 | # enables server list commands. Particularly needed if participating in a global network 88 | --comp-name-1=network 89 | --comp-class-1=org.kontalk.xmppserver.NetworkComponent 90 | 91 | # Phone number lookup component 92 | # enables discovery of contacts in the local/global network by their phone numbers 93 | --comp-name-2=probe 94 | --comp-class-2=org.kontalk.xmppserver.probe.ProbeComponent 95 | 96 | # For group chats 97 | --comp-name-3=multicast 98 | --comp-class-3=org.kontalk.xmppserver.ExtendedAddressing 99 | 100 | # External XMPP component protocol 101 | # needed for HttpFileUploadComponent 102 | --comp-name-4=ext 103 | --comp-class-4=tigase.server.ext.ComponentProtocol 104 | # these must match HttpFileUploadComponent configuration 105 | --external=media.{{ .Env.XMPP_SERVICE }}:secret:listen:5270 106 | 107 | # For other stuff, including OMEMO 108 | --comp-name-5=pubsub 109 | --comp-class-5=tigase.pubsub.PubSubComponent 110 | 111 | # GCM push notifications 112 | # remember to fix --sm-plugins too (see above) 113 | #--comp-name-6=push 114 | #--comp-class-6=org.kontalk.xmppserver.KontalkLegacyPushComponent 115 | #push/gcm-projectid=PROJECT-ID 116 | #push/gcm-apikey=API-KEY 117 | 118 | # Internal parameters 119 | # the following properties must not be changed unless you really know what you're doing 120 | basic-conf/auth-repo-params/sasl-mechs=EXTERNAL 121 | sess-man/plugins-conf/urn\:ietf\:params\:xml\:ns\:xmpp-sasl/factory=org.kontalk.xmppserver.auth.KontalkSaslServerFactory 122 | sess-man/plugins-conf/urn\:ietf\:params\:xml\:ns\:xmpp-sasl/mechanism-selector=org.kontalk.xmppserver.auth.KontalkMechanismSelector 123 | sess-man/plugins-conf/urn\:ietf\:params\:xml\:ns\:xmpp-sasl/callbackhandler-EXTERNAL=org.kontalk.xmppserver.auth.KontalkCertificateCallbackHandler 124 | sess-man/plugins-conf/presence-state/extended-presence-processors=org.kontalk.xmppserver.presence.PublicKeyPresence 125 | c2s/processors[s]=urn:xmpp:sm:3=org.kontalk.xmppserver.KontalkIOProcessor 126 | c2s/processors/urn\:xmpp\:sm\:3/ack-timeout[I]=60 127 | message-router/components/msg-receivers/amp.active[B]=false 128 | pubsub/pubsub-repo-class=tigase.pubsub.repository.PubSubDAOJDBC 129 | pubsub/persistent-pep[B]=true 130 | pubsub/send-last-published-item-on-presence[B]=true 131 | 132 | basic-conf/logging/handlers=biz.paluch.logging.gelf.jul.GelfLogHandler,java.util.logging.ConsoleHandler 133 | basic-conf/logging/java.util.logging.ConsoleHandler.level=ALL 134 | basic-conf/logging/biz.paluch.logging.gelf.jul.GelfLogHandler.level=ALL 135 | basic-conf/logging/biz.paluch.logging.gelf.jul.GelfLogHandler.host=udp:logstash 136 | basic-conf/logging/biz.paluch.logging.gelf.jul.GelfLogHandler.port=12201 137 | basic-conf/logging/biz.paluch.logging.gelf.jul.GelfLogHandler.version=1.1 138 | basic-conf/logging/biz.paluch.logging.gelf.jul.GelfLogHandler.facility={{ .Env.XMPP_SERVICE }} 139 | basic-conf/logging/biz.paluch.logging.gelf.jul.GelfLogHandler.extractStackTrace=true 140 | basic-conf/logging/biz.paluch.logging.gelf.jul.GelfLogHandler.filterStackTrace=true 141 | basic-conf/logging/biz.paluch.logging.gelf.jul.GelfLogHandler.timestampPattern=yyyy-MM-dd HH:mm:ss.SSSS 142 | basic-conf/logging/biz.paluch.logging.gelf.jul.GelfLogHandler.maximumMessageSize=8192 143 | 144 | --vhost-anonymous-enabled=false 145 | --vhost-tls-required=false 146 | --hardened-mode=true 147 | config-type=--gen-config-def 148 | -------------------------------------------------------------------------------- /data/tigase.conf.dist: -------------------------------------------------------------------------------- 1 | OSGI=${osgiEnabled} 2 | ENC="-Dfile.encoding=UTF-8 -Dsun.jnu.encoding=UTF-8" 3 | DRV="-Djdbc.drivers=com.mysql.jdbc.Driver:org.postgresql.Driver:org.apache.derby.jdbc.EmbeddedDriver" 4 | #GC="-XX:+UseBiasedLocking -XX:+UseConcMarkSweepGC -XX:+CMSIncrementalMode -XX:ParallelCMSThreads=2 -XX:-ReduceInitialCardMarks" 5 | #EX="-XX:+OptimizeStringConcat -XX:+DoEscapeAnalysis -XX:+UseNUMA" 6 | CLASSPATH="" 7 | JAVA_OPTIONS="${GC} ${EX} ${ENC} ${DRV} -server -Xms100M -Xmx512M -XX:PermSize=32m -XX:MaxPermSize=256m -XX:MaxDirectMemorySize=128m -Djava.library.path=jars -Djdk.tls.ephemeralDHKeySize=2048 -Dpgp.secret.public=server-public.key -Dpgp.secret.private=server-private.key -Dpgp.keyring=../data/keyring " 8 | TIGASE_CONFIG="etc/tigase.xml" 9 | TIGASE_OPTIONS=" --property-file etc/init.properties " 10 | -------------------------------------------------------------------------------- /data/trusted.pem.dist: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIHWTCCBUGgAwIBAgIDCkGKMA0GCSqGSIb3DQEBCwUAMHkxEDAOBgNVBAoTB1Jv 3 | b3QgQ0ExHjAcBgNVBAsTFWh0dHA6Ly93d3cuY2FjZXJ0Lm9yZzEiMCAGA1UEAxMZ 4 | Q0EgQ2VydCBTaWduaW5nIEF1dGhvcml0eTEhMB8GCSqGSIb3DQEJARYSc3VwcG9y 5 | dEBjYWNlcnQub3JnMB4XDTExMDUyMzE3NDgwMloXDTIxMDUyMDE3NDgwMlowVDEU 6 | MBIGA1UEChMLQ0FjZXJ0IEluYy4xHjAcBgNVBAsTFWh0dHA6Ly93d3cuQ0FjZXJ0 7 | Lm9yZzEcMBoGA1UEAxMTQ0FjZXJ0IENsYXNzIDMgUm9vdDCCAiIwDQYJKoZIhvcN 8 | AQEBBQADggIPADCCAgoCggIBAKtJNRFIfNImflOUz0Op3SjXQiqL84d4GVh8D57a 9 | iX3h++tykA10oZZkq5+gJJlz2uJVdscXe/UErEa4w75/ZI0QbCTzYZzA8pD6Ueb1 10 | aQFjww9W4kpCz+JEjCUoqMV5CX1GuYrz6fM0KQhF5Byfy5QEHIGoFLOYZcRD7E6C 11 | jQnRvapbjZLQ7N6QxX8KwuPr5jFaXnQ+lzNZ6MMDPWAzv/fRb0fEze5ig1JuLgia 12 | pNkVGJGmhZJHsK5I6223IeyFGmhyNav/8BBdwPSUp2rVO5J+TJAFfpPBLIukjmJ0 13 | FXFuC3ED6q8VOJrU0gVyb4z5K+taciX5OUbjchs+BMNkJyIQKopPWKcDrb60LhPt 14 | XapI19V91Cp7XPpGBFDkzA5CW4zt2/LP/JaT4NsRNlRiNDiPDGCbO5dWOK3z0luL 15 | oFvqTpa4fNfVoIZwQNORKbeiPK31jLvPGpKK5DR7wNhsX+kKwsOnIJpa3yxdUly6 16 | R9Wb7yQocDggL9V/KcCyQQNokszgnMyXS0XvOhAKq3A6mJVwrTWx6oUrpByAITGp 17 | rmB6gCZIALgBwJNjVSKRPFbnr9s6JfOPMVTqJouBWfmh0VMRxXudA/Z0EeBtsSw/ 18 | LIaRmXGapneLNGDRFLQsrJ2vjBDTn8Rq+G8T/HNZ92ZCdB6K4/jc0m+YnMtHmJVA 19 | BfvpAgMBAAGjggINMIICCTAdBgNVHQ4EFgQUdahxYEyIE/B42Yl3tW3Fid+8sXow 20 | gaMGA1UdIwSBmzCBmIAUFrUyG9TH8+DmjvO90rA67rI5GNGhfaR7MHkxEDAOBgNV 21 | BAoTB1Jvb3QgQ0ExHjAcBgNVBAsTFWh0dHA6Ly93d3cuY2FjZXJ0Lm9yZzEiMCAG 22 | A1UEAxMZQ0EgQ2VydCBTaWduaW5nIEF1dGhvcml0eTEhMB8GCSqGSIb3DQEJARYS 23 | c3VwcG9ydEBjYWNlcnQub3JnggEAMA8GA1UdEwEB/wQFMAMBAf8wXQYIKwYBBQUH 24 | AQEEUTBPMCMGCCsGAQUFBzABhhdodHRwOi8vb2NzcC5DQWNlcnQub3JnLzAoBggr 25 | BgEFBQcwAoYcaHR0cDovL3d3dy5DQWNlcnQub3JnL2NhLmNydDBKBgNVHSAEQzBB 26 | MD8GCCsGAQQBgZBKMDMwMQYIKwYBBQUHAgEWJWh0dHA6Ly93d3cuQ0FjZXJ0Lm9y 27 | Zy9pbmRleC5waHA/aWQ9MTAwNAYJYIZIAYb4QgEIBCcWJWh0dHA6Ly93d3cuQ0Fj 28 | ZXJ0Lm9yZy9pbmRleC5waHA/aWQ9MTAwUAYJYIZIAYb4QgENBEMWQVRvIGdldCB5 29 | b3VyIG93biBjZXJ0aWZpY2F0ZSBmb3IgRlJFRSwgZ28gdG8gaHR0cDovL3d3dy5D 30 | QWNlcnQub3JnMA0GCSqGSIb3DQEBCwUAA4ICAQApKIWuRKm5r6R5E/CooyuXYPNc 31 | 7uMvwfbiZqARrjY3OnYVBFPqQvX56sAV2KaC2eRhrnILKVyQQ+hBsuF32wITRHhH 32 | Va9Y/MyY9kW50SD42CEH/m2qc9SzxgfpCYXMO/K2viwcJdVxjDm1Luq+GIG6sJO4 33 | D+Pm1yaMMVpyA4RS5qb1MyJFCsgLDYq4Nm+QCaGrvdfVTi5xotSu+qdUK+s1jVq3 34 | VIgv7nSf7UgWyg1I0JTTrKSi9iTfkuO960NAkW4cGI5WtIIS86mTn9S8nK2cde5a 35 | lxuV53QtHA+wLJef+6kzOXrnAzqSjiL2jA3k2X4Ndhj3AfnvlpaiVXPAPHG0HRpW 36 | Q7fDCo1y/OIQCQtBzoyUoPkD/XFzS4pXM+WOdH4VAQDmzEoc53+VGS3FpQyLu7Xt 37 | hbNc09+4ufLKxw0BFKxwWMWMjTPUnWajGlCVI/xI4AZDEtnNp4Y5LzZyo4AQ5OHz 38 | 0ctbGsDkgJp8E3MGT9ujayQKurMcvEp4u+XjdTilSKeiHq921F73OIZWWonO1sOn 39 | ebJSoMbxhbQljPI/lrMQ2Y1sVzufb4Y6GIIiNsiwkTjbKqGTqoQ/9SdlrnPVyNXT 40 | d+pLncdBu8fA46A/5H2kjXPmEkvfoXNzczqA6NXLji/L6hOn1kGLrPo8idck9U60 41 | 4GGSt/M3mMS+lqO3ig== 42 | -----END CERTIFICATE----- 43 | -----BEGIN CERTIFICATE----- 44 | MIIHPTCCBSWgAwIBAgIBADANBgkqhkiG9w0BAQQFADB5MRAwDgYDVQQKEwdSb290 45 | IENBMR4wHAYDVQQLExVodHRwOi8vd3d3LmNhY2VydC5vcmcxIjAgBgNVBAMTGUNB 46 | IENlcnQgU2lnbmluZyBBdXRob3JpdHkxITAfBgkqhkiG9w0BCQEWEnN1cHBvcnRA 47 | Y2FjZXJ0Lm9yZzAeFw0wMzAzMzAxMjI5NDlaFw0zMzAzMjkxMjI5NDlaMHkxEDAO 48 | BgNVBAoTB1Jvb3QgQ0ExHjAcBgNVBAsTFWh0dHA6Ly93d3cuY2FjZXJ0Lm9yZzEi 49 | MCAGA1UEAxMZQ0EgQ2VydCBTaWduaW5nIEF1dGhvcml0eTEhMB8GCSqGSIb3DQEJ 50 | ARYSc3VwcG9ydEBjYWNlcnQub3JnMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC 51 | CgKCAgEAziLA4kZ97DYoB1CW8qAzQIxL8TtmPzHlawI229Z89vGIj053NgVBlfkJ 52 | 8BLPRoZzYLdufujAWGSuzbCtRRcMY/pnCujW0r8+55jE8Ez64AO7NV1sId6eINm6 53 | zWYyN3L69wj1x81YyY7nDl7qPv4coRQKFWyGhFtkZip6qUtTefWIonvuLwphK42y 54 | fk1WpRPs6tqSnqxEQR5YYGUFZvjARL3LlPdCfgv3ZWiYUQXw8wWRBB0bF4LsyFe7 55 | w2t6iPGwcswlWyCR7BYCEo8y6RcYSNDHBS4CMEK4JZwFaz+qOqfrU0j36NK2B5jc 56 | G8Y0f3/JHIJ6BVgrCFvzOKKrF11myZjXnhCLotLddJr3cQxyYN/Nb5gznZY0dj4k 57 | epKwDpUeb+agRThHqtdB7Uq3EvbXG4OKDy7YCbZZ16oE/9KTfWgu3YtLq1i6L43q 58 | laegw1SJpfvbi1EinbLDvhG+LJGGi5Z4rSDTii8aP8bQUWWHIbEZAWV/RRyH9XzQ 59 | QUxPKZgh/TMfdQwEUfoZd9vUFBzugcMd9Zi3aQaRIt0AUMyBMawSB3s42mhb5ivU 60 | fslfrejrckzzAeVLIL+aplfKkQABi6F1ITe1Yw1nPkZPcCBnzsXWWdsC4PDSy826 61 | YreQQejdIOQpvGQpQsgi3Hia/0PsmBsJUUtaWsJx8cTLc6nloQsCAwEAAaOCAc4w 62 | ggHKMB0GA1UdDgQWBBQWtTIb1Mfz4OaO873SsDrusjkY0TCBowYDVR0jBIGbMIGY 63 | gBQWtTIb1Mfz4OaO873SsDrusjkY0aF9pHsweTEQMA4GA1UEChMHUm9vdCBDQTEe 64 | MBwGA1UECxMVaHR0cDovL3d3dy5jYWNlcnQub3JnMSIwIAYDVQQDExlDQSBDZXJ0 65 | IFNpZ25pbmcgQXV0aG9yaXR5MSEwHwYJKoZIhvcNAQkBFhJzdXBwb3J0QGNhY2Vy 66 | dC5vcmeCAQAwDwYDVR0TAQH/BAUwAwEB/zAyBgNVHR8EKzApMCegJaAjhiFodHRw 67 | czovL3d3dy5jYWNlcnQub3JnL3Jldm9rZS5jcmwwMAYJYIZIAYb4QgEEBCMWIWh0 68 | dHBzOi8vd3d3LmNhY2VydC5vcmcvcmV2b2tlLmNybDA0BglghkgBhvhCAQgEJxYl 69 | aHR0cDovL3d3dy5jYWNlcnQub3JnL2luZGV4LnBocD9pZD0xMDBWBglghkgBhvhC 70 | AQ0ESRZHVG8gZ2V0IHlvdXIgb3duIGNlcnRpZmljYXRlIGZvciBGUkVFIGhlYWQg 71 | b3ZlciB0byBodHRwOi8vd3d3LmNhY2VydC5vcmcwDQYJKoZIhvcNAQEEBQADggIB 72 | ACjH7pyCArpcgBLKNQodgW+JapnM8mgPf6fhjViVPr3yBsOQWqy1YPaZQwGjiHCc 73 | nWKdpIevZ1gNMDY75q1I08t0AoZxPuIrA2jxNGJARjtT6ij0rPtmlVOKTV39O9lg 74 | 18p5aTuxZZKmxoGCXJzN600BiqXfEVWqFcofN8CCmHBh22p8lqOOLlQ+TyGpkO/c 75 | gr/c6EWtTZBzCDyUZbAEmXZ/4rzCahWqlwQ3JNgelE5tDlG+1sSPypZt90Pf6DBl 76 | Jzt7u0NDY8RD97LsaMzhGY4i+5jhe1o+ATc7iwiwovOVThrLm82asduycPAtStvY 77 | sONvRUgzEv/+PDIqVPfE94rwiCPCR/5kenHA0R6mY7AHfqQv0wGP3J8rtsYIqQ+T 78 | SCX8Ev2fQtzzxD72V7DX3WnRBnc0CkvSyqD/HMaMyRa+xMwyN2hzXwj7UfdJUzYF 79 | CpUCTPJ5GhD22Dp1nPMd8aINcGeGG7MW9S/lpOt5hvk9C8JzC6WZrG/8Z7jlLwum 80 | GCSNe9FINSkYQKyTYOGWhlC0elnYjyELn8+CkcY7v2vcB5G5l1YjqrZslMZIBjzk 81 | zk6q5PYvCdxTby78dOs6Y5nCpqyJvKeyRKANihDjbPIky/qbn3BHLt4Ui9SyIAmW 82 | omTxJBzcoTWcFbLUvFUufQb1nA5V9FrWk9p2rSVzTMVD 83 | -----END CERTIFICATE----- 84 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | # Services definition for a Kontalk server 2 | # DO NOT RUN docker-compose on this file directly 3 | # Use ./launcher start 4 | 5 | version: '2' 6 | 7 | services: 8 | db: 9 | container_name: "${INSTANCE_NAME}_db" 10 | image: mysql:5.6 11 | volumes: 12 | - db_data:/var/lib/mysql 13 | - ./mysql/my.cnf:/etc/mysql/conf.d/my.cnf 14 | restart: on-failure 15 | environment: 16 | - MYSQL_DATABASE=kontalk 17 | - MYSQL_USER=kontalk 18 | - MYSQL_PASSWORD 19 | - MYSQL_ROOT_PASSWORD 20 | networks: 21 | - default 22 | 23 | xmpp: 24 | container_name: "${INSTANCE_NAME}_xmpp" 25 | depends_on: 26 | - db 27 | image: kontalk/xmppserver:${IMAGE_VERSION} 28 | ports: 29 | - "${XMPP_LISTEN_PORT}:5222" 30 | - "${XMPPS_LISTEN_PORT}:5223" 31 | - "${XMPPS2S_LISTEN_PORT}:5269" 32 | volumes: 33 | - xmpp_data:/home/kontalk/data 34 | - ./config:/tmp/data 35 | restart: on-failure 36 | logging: 37 | options: 38 | max-size: "10m" 39 | max-file: "100" 40 | environment: 41 | - MYSQL_DATABASE=kontalk 42 | - MYSQL_USER=kontalk 43 | - MYSQL_PASSWORD 44 | - MYSQL_ROOT_PASSWORD 45 | - MYSQL_TIMEZONE 46 | - DATABASE_BASELINE 47 | - XMPP_SERVICE 48 | - XMPP_LISTEN_PORT 49 | - XMPPS_LISTEN_PORT 50 | - XMPPS2S_LISTEN_PORT 51 | networks: 52 | - default 53 | - elk 54 | 55 | httpupload: 56 | container_name: "${INSTANCE_NAME}_httpupload" 57 | image: kontalk/httpupload 58 | ports: 59 | - "${HTTPUPLOAD_LISTEN_PORT}:8828" 60 | volumes: 61 | - httpupload_data:/home/kontalk/disk 62 | - ./config/config.yml.in:/tmp/config.yml.in 63 | restart: on-failure 64 | logging: 65 | options: 66 | max-size: "10m" 67 | max-file: "10" 68 | environment: 69 | - XMPP_SERVICE 70 | - HTTPUPLOAD_MAX_SIZE 71 | - HTTPUPLOAD_LISTEN_PORT 72 | - HTTPUPLOAD_PUT_URL 73 | - HTTPUPLOAD_GET_URL 74 | networks: 75 | - default 76 | - elk 77 | 78 | volumes: 79 | db_data: 80 | xmpp_data: 81 | httpupload_data: 82 | 83 | networks: 84 | default: 85 | elk: 86 | # Uncomment to enable link to ELK logging 87 | # external: 88 | # name: "${INSTANCE_NAME}log_elk" 89 | -------------------------------------------------------------------------------- /httpupload/Dockerfile: -------------------------------------------------------------------------------- 1 | # use BRANCH variable to provide source code branch 2 | FROM debian:stretch-backports 3 | LABEL "org.kontalk"="Kontalk devteam" 4 | LABEL version="1.0" 5 | LABEL description="Kontalk server HTTP upload component image" 6 | 7 | # install packages 8 | RUN apt-get -qq update && apt-get -qq -y --no-install-recommends install \ 9 | wget git openssl python3 python3-pip python3-setuptools 10 | 11 | # install tools 12 | ENV DOCKERIZE_VERSION v0.5.0 13 | RUN wget https://github.com/jwilder/dockerize/releases/download/$DOCKERIZE_VERSION/dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz \ 14 | && tar -C /usr/local/bin -xzvf dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz \ 15 | && rm dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz 16 | RUN wget https://raw.githubusercontent.com/vishnubob/wait-for-it/master/wait-for-it.sh \ 17 | && mv wait-for-it.sh /usr/local/bin/wait-for-it \ 18 | && chmod +x /usr/local/bin/wait-for-it 19 | 20 | # create kontalk user 21 | RUN useradd --no-log-init -ms /bin/bash kontalk 22 | 23 | # will now work from the kontalk user 24 | USER kontalk 25 | WORKDIR /home/kontalk 26 | 27 | # install HTTP upload component 28 | USER root 29 | COPY install-httpupload.sh /home/kontalk/ 30 | RUN chown kontalk:kontalk /home/kontalk/install-httpupload.sh && chmod +x /home/kontalk/install-httpupload.sh 31 | USER kontalk 32 | RUN ./install-httpupload.sh 33 | 34 | # install requirements 35 | USER root 36 | RUN pip3 install -r /home/kontalk/HttpUploadComponent/requirements.txt 37 | 38 | # copy the entrypoint script 39 | # we don't do this before to take advantage of caching 40 | # when just changing the entrypoint script 41 | COPY entrypoint.sh /home/kontalk/ 42 | RUN chown kontalk:kontalk /home/kontalk/entrypoint.sh && chmod +x /home/kontalk/entrypoint.sh 43 | 44 | # back to kontalk user and start everything up 45 | USER kontalk 46 | RUN mkdir -p ${HOME}/disk 47 | ENTRYPOINT ["/home/kontalk/entrypoint.sh"] 48 | -------------------------------------------------------------------------------- /httpupload/README.md: -------------------------------------------------------------------------------- 1 | Kontalk HTTP upload component image 2 | =================================== 3 | 4 | This is a Docker image for the HTTP upload component of a Kontalk server. 5 | 6 | To build this image just run this from a terminal: 7 | 8 | ```shell 9 | docker build -t kontalk/httpupload . 10 | ``` 11 | 12 | The following environment variables are mandatory: 13 | 14 | * `HTTPUPLOAD_MAX_SIZE`: max upload file size in bytes 15 | * `HTTPUPLOAD_LISTEN_PORT`: service port exposed to host 16 | * `HTTPUPLOAD_PUT_URL`: upload URL for clients (must be a public URL) 17 | * `HTTPUPLOAD_GET_URL`: download URL for clients (must be a public URL) 18 | -------------------------------------------------------------------------------- /httpupload/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | 4 | # create SSL certificate if needed 5 | SSL_CERT="${HOME}/HttpUploadComponent/server.crt" 6 | SSL_KEY="${HOME}/HttpUploadComponent/server.key" 7 | if [ ! -f ${SSL_CERT} ] || [ ! -f ${SSL_KEY} ]; 8 | then 9 | echo "Generating SSL certificate" 10 | openssl req -x509 -subj "/C=US/ST=Denial/L=Springfield/O=Dis/CN=${XMPP_SERVICE}" -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365 -nodes 11 | cp cert.pem ${SSL_CERT} && 12 | cp key.pem ${SSL_KEY} && 13 | rm cert.pem key.pem 14 | fi 15 | 16 | cd ${HOME}/HttpUploadComponent 17 | exec dockerize \ 18 | -template /tmp/config.yml.in:config.yml \ 19 | python3 httpupload/server.py 20 | -------------------------------------------------------------------------------- /httpupload/install-httpupload.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | 4 | yell() { echo "$0: $*" >&2; } 5 | die() { yell "$*"; exit 1; } 6 | try() { "$@" || die "cannot $*"; } 7 | check_for() { which $@ >/dev/null || die "Unable to locate $*"; } 8 | 9 | check_programs() 10 | { 11 | # check for git 12 | check_for git 13 | } 14 | 15 | # check for needed programs 16 | check_programs 17 | 18 | yell "Cloning repositories" 19 | 20 | try git clone https://github.com/kontalk/HttpUploadComponent.git 21 | -------------------------------------------------------------------------------- /kontalk-setup: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Setup script for Kontalk Docker server 3 | 4 | cd "$(dirname "$0")" 5 | 6 | [ -f local.properties.dist ] && . local.properties.dist 7 | [ -f local.properties ] && . local.properties 8 | 9 | # default values 10 | [ -z "${XMPP_SERVICE}" ] && XMPP_SERVICE=$(hostname -d) 11 | [ -z "${MYSQL_TIMEZONE}" -a -f /etc/timezone ] && MYSQL_TIMEZONE=$(cat /etc/timezone) 12 | [ -z "${HTTPUPLOAD_MAX_SIZE}" ] && HTTPUPLOAD_MAX_SIZE=20971520 13 | [ -z "${XMPP_LISTEN_PORT}" ] && XMPP_LISTEN_PORT=5222 14 | [ -z "${XMPPS_LISTEN_PORT}" ] && XMPPS_LISTEN_PORT=5223 15 | [ -z "${XMPPS2S_LISTEN_PORT}" ] && XMPPS2S_LISTEN_PORT=5269 16 | [ -z "${HTTPUPLOAD_LISTEN_PORT}" ] && HTTPUPLOAD_LISTEN_PORT=8828 17 | [ -z "${BACKUP_PATH}" ] && BACKUP_PATH= 18 | 19 | bold=$(tput bold) 20 | red=$(tput setaf 1) 21 | yellow=$(tput setaf 3) 22 | green=$(tput setaf 2) 23 | reset=$(tput sgr0) 24 | 25 | echo "Please give a name to your new Kontalk server instance." 26 | 27 | if [ -f local.properties ]; then 28 | echo "${bold}If you have existing containers and need to change this, please exit now (Ctrl+C)," 29 | echo "destroy the old containers and launch kontalk-setup again.${reset}" 30 | fi 31 | 32 | # instance name (container prefix) 33 | read -p "Kontalk instance name [${INSTANCE_NAME}]: " new_value 34 | if [ ! -z $new_value ]; then 35 | INSTANCE_NAME=$new_value 36 | fi 37 | 38 | # version/branch to build 39 | echo 40 | echo "Kontalk is available in the following branches:" 41 | echo " ${red}master${reset}: bleeding-edge, latest modifications. Possibly unstable. Use for development only." 42 | echo " ${yellow}staging${reset}: used in Kontalk test server. It should have the latest features with a certain degree of stability." 43 | echo " ${green}production${reset}: used in Kontalk production server. Stable and tested." 44 | echo "You can also specify a version tag." 45 | echo 46 | 47 | read -p "Kontalk version/branch to build [${VERSION}]: " new_value 48 | if [ ! -z $new_value ]; then 49 | VERSION=$new_value 50 | fi 51 | 52 | # XMPP service name 53 | read -p "XMPP service name [${XMPP_SERVICE}]: " new_value 54 | if [ ! -z $new_value ]; then 55 | XMPP_SERVICE=$new_value 56 | fi 57 | 58 | if [ -z "${XMPP_SERVICE}" ]; then 59 | echo "XMPP service name cannot be empty." 60 | exit 1 61 | fi 62 | 63 | # XMPP plain listen port 64 | read -p "XMPP plain listen port [${XMPP_LISTEN_PORT}]: " new_value 65 | if [ ! -z $new_value ]; then 66 | XMPP_LISTEN_PORT=$new_value 67 | fi 68 | 69 | # XMPP secure listen port 70 | read -p "XMPP secure listen port [${XMPPS_LISTEN_PORT}]: " new_value 71 | if [ ! -z $new_value ]; then 72 | XMPPS_LISTEN_PORT=$new_value 73 | fi 74 | 75 | # XMPP s2s listen port 76 | read -p "XMPP s2s listen port [${XMPPS2S_LISTEN_PORT}]: " new_value 77 | if [ ! -z $new_value ]; then 78 | XMPPS2S_LISTEN_PORT=$new_value 79 | fi 80 | 81 | # MySQL root password 82 | read -p "MySQL root password [${MYSQL_ROOT_PASSWORD}]: " new_value 83 | if [ ! -z $new_value ]; then 84 | MYSQL_ROOT_PASSWORD=$new_value 85 | fi 86 | 87 | if [ -z ${MYSQL_ROOT_PASSWORD} ]; then 88 | echo "MySQL root password cannot be empty." 89 | exit 1 90 | fi 91 | 92 | # MySQL kontalk password 93 | read -p "MySQL kontalk password [${MYSQL_PASSWORD}]: " new_value 94 | if [ ! -z $new_value ]; then 95 | MYSQL_PASSWORD=$new_value 96 | fi 97 | 98 | if [ -z ${MYSQL_PASSWORD} ]; then 99 | echo "MySQL kontalk password cannot be empty." 100 | exit 1 101 | fi 102 | 103 | # MySQL time zone 104 | read -p "MySQL time zone [${MYSQL_TIMEZONE}]: " new_value 105 | if [ ! -z $new_value ]; then 106 | MYSQL_TIMEZONE=$new_value 107 | fi 108 | 109 | # HTTP upload component parameters 110 | echo 111 | echo "The HTTP file upload service is used by clients to upload and download media." 112 | echo "It should be exposed directly or better through a reverse proxy (e.g. Nginx)." 113 | echo "We will ask you for the listen port exposed to the host system and the URLs seen by clients." 114 | echo "Note that those URLs should be available from the outside, i.e. from the Internet" 115 | echo 116 | 117 | read -p "HTTP file upload service listen port [${HTTPUPLOAD_LISTEN_PORT}]: " new_value 118 | if [ ! -z $new_value ]; then 119 | HTTPUPLOAD_LISTEN_PORT=$new_value 120 | fi 121 | 122 | read -p "HTTP file upload URL [${HTTPUPLOAD_PUT_URL}]: " new_value 123 | if [ ! -z $new_value ]; then 124 | HTTPUPLOAD_PUT_URL=$new_value 125 | fi 126 | 127 | if [ -z "${HTTPUPLOAD_PUT_URL}" ]; then 128 | echo "HTTP file upload URL cannot be empty." 129 | exit 1 130 | fi 131 | 132 | read -p "HTTP file download URL [${HTTPUPLOAD_GET_URL}]: " new_value 133 | if [ ! -z $new_value ]; then 134 | HTTPUPLOAD_GET_URL=$new_value 135 | fi 136 | 137 | if [ -z "${HTTPUPLOAD_GET_URL}" ]; then 138 | echo "HTTP file download URL cannot be empty." 139 | exit 1 140 | fi 141 | 142 | # max HTTP upload file size 143 | read -p "Max HTTP upload file size [${HTTPUPLOAD_MAX_SIZE}]: " new_value 144 | if [ ! -z $new_value ]; then 145 | HTTPUPLOAD_MAX_SIZE=$new_value 146 | fi 147 | 148 | # Backup path 149 | read -p "Backup path (blank to disable backups) []: " new_value 150 | if [ ! -z $new_value ]; then 151 | BACKUP_PATH=$new_value 152 | fi 153 | 154 | cat <local.properties 155 | # Kontalk server configuration 156 | # if you edit this file you must rebuild your containers: 157 | # ./launcher rebuild 158 | 159 | INSTANCE_NAME=${INSTANCE_NAME} 160 | 161 | # version/branch to build 162 | VERSION=${VERSION} 163 | 164 | # XMPP parameters 165 | XMPP_SERVICE=${XMPP_SERVICE} 166 | XMPP_LISTEN_PORT=${XMPP_LISTEN_PORT} 167 | XMPPS_LISTEN_PORT=${XMPPS_LISTEN_PORT} 168 | XMPPS2S_LISTEN_PORT=${XMPPS2S_LISTEN_PORT} 169 | 170 | # Database parameters 171 | 172 | # kontalk database user password 173 | MYSQL_PASSWORD=${MYSQL_PASSWORD} 174 | # root database user password 175 | MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD} 176 | # database timezone 177 | MYSQL_TIMEZONE=${MYSQL_TIMEZONE} 178 | # database initial baseline 179 | # alter this only if you know what you are doing 180 | DATABASE_BASELINE=1 181 | 182 | # Other parameters 183 | 184 | # Max upload file size 185 | HTTPUPLOAD_MAX_SIZE=${HTTPUPLOAD_MAX_SIZE} 186 | 187 | # HTTP listen port 188 | HTTPUPLOAD_LISTEN_PORT=${HTTPUPLOAD_LISTEN_PORT} 189 | 190 | # HTTP URLs 191 | HTTPUPLOAD_PUT_URL=${HTTPUPLOAD_PUT_URL} 192 | HTTPUPLOAD_GET_URL=${HTTPUPLOAD_GET_URL} 193 | 194 | # Backup location 195 | BACKUP_PATH=${BACKUP_PATH} 196 | EOF 197 | 198 | rm -f .version 199 | 200 | echo 201 | echo "You can now build the images by running \`./launcher bootstrap\`" 202 | -------------------------------------------------------------------------------- /launcher: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Launcher script for Kontalk Docker server 3 | # Inspired by the Discourse launcher 4 | 5 | set -e 6 | 7 | usage () { 8 | echo "Usage: launcher COMMAND" 9 | echo "Commands:" 10 | echo " start: Start/initialize containers" 11 | echo " stop: Stop running containers" 12 | echo " restart: Restart containers" 13 | echo " destroy: Stop and remove containers" 14 | echo " enter: Open a shell to run commands inside the xmpp container" 15 | echo " logs: View the Docker logs for containers" 16 | echo " bootstrap: Bootstrap containers for the config" 17 | echo " rebuild: Rebuild containers (destroy old, bootstrap, start new)" 18 | echo " backup: Initiate server backup procedure" 19 | echo " restore: Restore a previously generated backup" 20 | echo 21 | echo "Any other command will be passed through to docker-compose, including all arguments." 22 | exit 1 23 | } 24 | 25 | command=$1 26 | 27 | if [ -z "$command" ]; then 28 | usage 29 | fi 30 | 31 | cd "$(dirname "$0")" 32 | 33 | docker_path=`which docker.io || which docker` 34 | dockercompose_path=`which docker-compose` 35 | gpg_path=`which gpg2 || which gpg` 36 | config_file=local.properties 37 | 38 | # escape sequences for output 39 | set +e 40 | bold=$(tput bold 2>/dev/null || false) 41 | normal=$(tput sgr0 2>/dev/null || false) 42 | set -e 43 | 44 | install_docker() { 45 | echo "Docker is not installed, you will need to install Docker in order to run Kontalk" 46 | echo "See https://docs.docker.com/installation/" 47 | exit 1 48 | } 49 | 50 | install_dockercompose() { 51 | echo "Docker Compose is not installed, you will need to install Docker Compose in order to run Kontalk" 52 | echo "See https://docs.docker.com/compose/install/" 53 | exit 1 54 | } 55 | 56 | run_setup_first() { 57 | echo "Run \`./kontalk-setup\` first." 58 | exit 1 59 | } 60 | 61 | check_prereqs() { 62 | if [ -z ${docker_path} ]; then 63 | install_docker 64 | fi 65 | if [ -z ${dockercompose_path} ]; then 66 | install_dockercompose 67 | fi 68 | if [ ! -f ${config_file} ]; then 69 | run_setup_first 70 | fi 71 | } 72 | 73 | check_version() { 74 | if [ ! -f .version ]; then 75 | echo "Run \`./launcher bootstrap\` first." 76 | exit 1 77 | fi 78 | } 79 | 80 | # check prerequisites 81 | check_prereqs 82 | 83 | # load configuration 84 | set -a 85 | . local.properties 86 | set +a 87 | 88 | DATADIR=data 89 | CONFDIR=config 90 | SSL_TRUSTED=trusted.pem 91 | TIGASE_CONF=init.properties.in 92 | TIGASE_ENV=tigase.conf 93 | HTTUPLOAD_CONF=config.yml.in 94 | REPO_URL=https://github.com/kontalk/tigase-kontalk.git 95 | 96 | docker_compose() { 97 | check_version 98 | (export IMAGE_VERSION=$(cat .version); set -x; ${dockercompose_path} -p ${INSTANCE_NAME} $*) 99 | } 100 | 101 | docker_compose_internal() { 102 | check_version 103 | (export IMAGE_VERSION=$(cat .version); ${dockercompose_path} -p ${INSTANCE_NAME} $*) 104 | } 105 | 106 | docker_compose_exec() { 107 | check_version 108 | export IMAGE_VERSION=$(cat .version); set -x; exec ${dockercompose_path} -p ${INSTANCE_NAME} $* 109 | } 110 | 111 | monitor_docker_build() { 112 | image="$1" 113 | base="$2" 114 | shift 2 115 | 116 | if [ -n "${DEBUG}" ]; then 117 | ${docker_path} build -t ${image} $* ${base} 118 | else 119 | ${docker_path} build -t ${image} $* ${base} >/dev/null & 120 | docker_pid=$! 121 | 122 | trap "kill ${docker_pid} 2>/dev/null" EXIT 123 | 124 | spin[0]="-" 125 | spin[1]="\\" 126 | spin[2]="|" 127 | spin[3]="/" 128 | 129 | echo -n "${image} ${spin[0]}" 130 | while kill -0 ${docker_pid} 2>/dev/null 131 | do 132 | for i in "${spin[@]}" 133 | do 134 | echo -ne "\b$i" 135 | sleep 0.1 136 | done 137 | done 138 | 139 | trap - EXIT 140 | wait ${docker_pid} && echo -e "\bOK" 141 | fi 142 | } 143 | 144 | run_bootstrap() { 145 | # get information about what we are going to build 146 | build=${VERSION} 147 | serverbuild=${VERSION} 148 | docker_tag=$(echo ${VERSION} | colrm 8) 149 | 150 | refs=$(git ls-remote ${REPO_URL} ${VERSION}) 151 | commit=$(echo "${refs}" | cut -f 1 -) 152 | ref=$(echo "${refs}" | cut -f 2 -) 153 | 154 | echo ${ref} | grep heads >/dev/null && 155 | docker_tag=$(echo ${commit} | colrm 8) && 156 | build=${commit} && 157 | echo "${bold}Building images for branch ${VERSION} (${commit})${normal}" 158 | echo ${ref} | grep tags >/dev/null && 159 | docker_tag=${build} && 160 | echo "${bold}Building images for version ${VERSION}${normal}" 161 | 162 | # build images 163 | echo "This could take several minutes." 164 | docker pull kontalk/xmppserver:${docker_tag} || monitor_docker_build kontalk/xmppserver:${docker_tag} tigase --build-arg BRANCH=${build} --build-arg SERVER_BRANCH=${serverbuild} 165 | monitor_docker_build kontalk/httpupload httpupload 166 | echo 167 | 168 | # ensure config directory exists 169 | mkdir -p ${CONFDIR} 170 | 171 | # check GPG key 172 | if [ ! -f ${CONFDIR}/server-private.key ] || [ ! -f ${CONFDIR}/server-public.key ]; then 173 | echo "${bold}Not using provided GPG server key, I'll generate one later automatically.${normal}" 174 | echo "You can provide a GPG server key by exporting it into ${CONFDIR}/server-private.key and ${CONFDIR}/server-public.key" 175 | echo "Please note that the private key MUST NOT be password-protected." 176 | echo 177 | fi 178 | 179 | # check if private GPG key is not password-protected 180 | if [ -f ${CONFDIR}/server-private.key ] && ${gpg_path} --list-packets ${CONFDIR}/server-private.key | grep protected &>/dev/null; then 181 | echo "${bold}The provided GPG server key is password-protected.${normal}" 182 | echo "That can't be used in an automated system. Please remove the passphrase from the private key using GnuPG and export it again." 183 | exit 1 184 | fi 185 | 186 | # check certificate 187 | if [ ! -f ${CONFDIR}/privatekey.pem ] || [ ! -f ${CONFDIR}/certificate.pem ]; then 188 | echo "${bold}Not using provided X.509 certificate, I'll generate one later automatically.${normal}" 189 | echo "If you want to provide an existing X.509 certificate for the server," 190 | echo "you can copy it into ${CONFDIR}/privatekey.pem and ${CONFDIR}/certificate.pem" 191 | echo "An optional CA chain can be provided into ${CONFDIR}/cachain.pem" 192 | echo 193 | fi 194 | 195 | # check trusted.pem 196 | if [ ! -f ${CONFDIR}/${SSL_TRUSTED} ]; 197 | then 198 | # copy default trusted certs bundle 199 | echo "Using default trusted certs bundle" 200 | cp ${DATADIR}/${SSL_TRUSTED}.dist ${CONFDIR}/${SSL_TRUSTED} 201 | echo 202 | fi 203 | 204 | # check init.properties 205 | if [ ! -f ${CONFDIR}/${TIGASE_CONF} ]; 206 | then 207 | echo "Using default Tigase configuration" 208 | cp ${DATADIR}/${TIGASE_CONF}.dist ${CONFDIR}/${TIGASE_CONF} 209 | echo 210 | fi 211 | 212 | if [ ! -f ${CONFDIR}/${TIGASE_ENV} ]; 213 | then 214 | echo "Using default Tigase environment" 215 | cp ${DATADIR}/${TIGASE_ENV}.dist ${CONFDIR}/${TIGASE_ENV} 216 | echo 217 | fi 218 | 219 | # check config.yml (httpupload) 220 | if [ ! -f ${CONFDIR}/${HTTUPLOAD_CONF} ]; 221 | then 222 | echo "Using default HTTP upload component configuration" 223 | cp ${DATADIR}/${HTTUPLOAD_CONF}.dist ${CONFDIR}/${HTTUPLOAD_CONF} 224 | echo 225 | fi 226 | 227 | # trusted keystore 228 | rm -f ${CONFDIR}/truststore 229 | if [ -d trustedcerts ]; then 230 | for i in trustedcerts/*.cer; do 231 | keytool -importcert -keystore ${CONFDIR}/truststore -storepass truststore -noprompt -alias $(basename ${i} .cer) -file ${i} &>/dev/null 232 | done 233 | fi 234 | 235 | echo ${docker_tag} > .version 236 | } 237 | 238 | run_start() { 239 | docker_compose up -d $* 240 | } 241 | 242 | run_stop() { 243 | docker_compose stop -t 10 $* 244 | } 245 | 246 | run_backup() { 247 | check_version 248 | 249 | if [[ ! -d "${BACKUP_PATH}" ]]; then 250 | echo "Backup path not configured or not a directory. Please configure an accessible directory in the BACKUP_PATH configuration key in local.properties." 251 | exit 1 252 | fi 253 | 254 | # create temporary directory 255 | OUTDIR="${BACKUP_PATH}/${INSTANCE_NAME}-`date +%Y-%m-%d_%H-%M-%S`" 256 | mkdir -p "${OUTDIR}/db" 257 | mkdir -p "${OUTDIR}/httpupload" 258 | mkdir -p "${OUTDIR}/xmpp" 259 | 260 | # dump the database 261 | echo "${bold}Dumping database${normal}" 262 | # TODO fallback to an emergency container if original fails 263 | if ! docker_compose exec -T db /usr/bin/mysqldump \ 264 | --skip-opt \ 265 | --single-transaction \ 266 | --quick \ 267 | --create-options \ 268 | --extended-insert \ 269 | --routines \ 270 | --set-charset \ 271 | --no-autocommit \ 272 | --user=kontalk --password="${MYSQL_PASSWORD}" \ 273 | kontalk >"${OUTDIR}/db/kontalk.sql" ; then 274 | echo 275 | echo -e "${bold}Unable to backup database. Ensure the database container is running by launching: \`./launcher start db\`${normal}" && 276 | exit 1 277 | fi 278 | 279 | # copy httpupload files 280 | # not really transactional, but we can live with it 281 | echo "${bold}Dumping httpupload files${normal}" 282 | docker run --rm -v "${INSTANCE_NAME}_httpupload_data:/out_data" \ 283 | busybox tar -C /out_data -cvf - . >"${OUTDIR}/httpupload/disk.tar" 284 | 285 | # copy xmpp files 286 | # TODO create kyoto cabinet tools image based on busybox so we can use kchashmgr copy 287 | echo "${bold}Dumping keyring${normal}" 288 | docker run --rm -v "${INSTANCE_NAME}_xmpp_data:/out_data" \ 289 | busybox cat /out_data/keyring.kch >"${OUTDIR}/xmpp/keyring.kch" 290 | 291 | # create the backup file (intentionally manually crafted list of files) 292 | echo "${bold}Creating backup archive${normal}" 293 | OUTFILE="${OUTDIR}.tar.gz" 294 | tar -C "${OUTDIR}" -cvzf "${OUTFILE}" \ 295 | "db/" \ 296 | "httpupload/" \ 297 | "xmpp/" 298 | rm -fR "${OUTDIR}" 299 | 300 | echo 301 | echo "${bold}Backup created: ${OUTFILE}${normal}" 302 | } 303 | 304 | run_restore() { 305 | check_version 306 | 307 | RESTORE_FILE="$1" 308 | # TODO if $1 is empty, take latest (by name) file in BACKUP_PATH/${INSTANCE_NAME}_*.tar.gz 309 | if [[ "${RESTORE_FILE}" == "" ]]; then 310 | echo "Usage: launcher restore " 311 | exit 1 312 | fi 313 | if [[ ! -f "${RESTORE_FILE}" ]]; then 314 | echo "Unable to read backup file ${RESTORE_FILE}" 315 | exit 1 316 | fi 317 | 318 | # ask for confirmation 319 | echo "${bold}You are about to restore the backup from:" 320 | echo " ${RESTORE_FILE}" 321 | echo 322 | echo "Any existing containers and their data in instance '${INSTANCE_NAME}' WILL BE DESTROYED.${normal}" 323 | echo 324 | read -p "Type 'OK' to proceed: " restore_ack 325 | [[ "${restore_ack}" == "OK" ]] || exit 1 326 | 327 | echo 328 | # take down the whole stack and re-create it 329 | echo "${bold}Rebuilding all containers and data${normal}" 330 | docker_compose down -v 331 | docker_compose up --no-start 332 | 333 | # restore database 334 | echo 335 | echo "${bold}Restoring database${normal}" 336 | 337 | # wait for the database to spin up 338 | docker_compose up -d db 339 | while ! docker_compose exec db mysql -u kontalk -p"${MYSQL_PASSWORD}" kontalk -e 'status' &>/dev/null ; do 340 | echo "Waiting for database connection..." 341 | sleep 4 342 | done 343 | 344 | tar -xOzf "${RESTORE_FILE}" "db/kontalk.sql" | 345 | docker exec -i $(docker_compose_internal ps -q db) \ 346 | mysql -u kontalk -p"${MYSQL_PASSWORD}" kontalk 347 | 348 | # restore httpupload files 349 | echo 350 | echo "${bold}Restoring httpupload files${normal}" 351 | docker_compose up -d httpupload 352 | 353 | tar -xOzf "${RESTORE_FILE}" "httpupload/disk.tar" | 354 | docker exec -i $(docker_compose_internal ps -q httpupload) \ 355 | tar -C /home/kontalk/disk -xf - 356 | 357 | # restore xmpp data 358 | echo 359 | echo "${bold}Restoring keyring${normal}" 360 | docker_compose up -d xmpp 361 | 362 | tar -xOzf "${RESTORE_FILE}" "xmpp/keyring.kch" | 363 | docker exec -i $(docker_compose_internal ps -q xmpp) \ 364 | tee /home/kontalk/data/keyring.kch >/dev/null 365 | 366 | echo 367 | echo "${bold}Server should now be up and running.${normal}" 368 | } 369 | 370 | case "$command" in 371 | bootstrap) 372 | run_bootstrap 373 | echo "${bold}Successfully bootstrapped, to startup use \`./launcher start\`${normal}" 374 | exit 0 375 | ;; 376 | 377 | start) 378 | shift 1 379 | run_start $* 380 | exit 0 381 | ;; 382 | 383 | stop) 384 | shift 1 385 | run_stop $* 386 | exit 0 387 | ;; 388 | 389 | restart) 390 | shift 1 391 | run_stop $* 392 | run_start $* 393 | exit 0 394 | ;; 395 | 396 | rebuild) 397 | echo "${bold}Stopping and removing old containers${normal}" 398 | docker_compose down 399 | 400 | run_bootstrap 401 | run_start 402 | exit 0 403 | ;; 404 | 405 | destroy) 406 | docker_compose down 407 | exit 0 408 | ;; 409 | 410 | backup) 411 | run_backup 412 | exit 0 413 | ;; 414 | 415 | restore) 416 | shift 1 417 | run_restore $* 418 | exit 0 419 | ;; 420 | 421 | enter) 422 | docker_compose_exec exec xmpp /bin/bash --login 423 | ;; 424 | 425 | root) 426 | docker_compose_exec exec --privileged --user root xmpp /bin/bash --login 427 | ;; 428 | 429 | *) 430 | shift 1 431 | docker_compose_exec ${command} $* 432 | ;; 433 | 434 | esac 435 | 436 | usage 437 | -------------------------------------------------------------------------------- /letsencrypt/post-hook.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # post-hook script for certbot 3 | # installs certificates and starts the containers 4 | set -e 5 | 6 | cd "$(dirname "$0")" 7 | 8 | . ../local.properties 9 | 10 | install_certificate() { 11 | DOMAIN="$1" 12 | LIVEDIR="/etc/letsencrypt/live/${DOMAIN}" 13 | if [ ! -d ${LIVEDIR} ]; then 14 | >&2 echo "Error: certificates not found." 15 | return 16 | fi 17 | 18 | # download CA certificates 19 | wget -q https://letsencrypt.org/certs/lets-encrypt-r3.pem -O /tmp/level2.pem 20 | wget -q https://letsencrypt.org/certs/isrgrootx1.pem -O /tmp/level1.pem 21 | 22 | cp ${LIVEDIR}/cert.pem ../config/certificate.pem 23 | cp ${LIVEDIR}/privkey.pem ../config/privatekey.pem 24 | cat /tmp/level2.pem /tmp/level1.pem >../config/cachain.pem 25 | } 26 | 27 | if [ -z "${XMPP_SERVICE}" ]; then 28 | echo "No domain defined. Skipping certificate installation." 29 | else 30 | install_certificate "${XMPP_SERVICE}" 31 | fi 32 | 33 | echo "Restarting Kontalk server." 34 | ../launcher restart 35 | -------------------------------------------------------------------------------- /local.properties.dist: -------------------------------------------------------------------------------- 1 | # instance name 2 | INSTANCE_NAME=prime 3 | 4 | # version/branch to build 5 | VERSION=staging 6 | 7 | # XMPP parameters 8 | XMPP_SERVICE=prime.kontalk.net 9 | XMPP_LISTEN_PORT=5222 10 | XMPPS_LISTEN_PORT=5223 11 | XMPPS2S_LISTEN_PORT=5269 12 | 13 | # Database parameters 14 | 15 | # kontalk database user password 16 | MYSQL_PASSWORD=kontalk 17 | # root database user password 18 | MYSQL_ROOT_PASSWORD=root 19 | # database timezone 20 | MYSQL_TIMEZONE= 21 | # database initial baseline 22 | # alter this only if you know what you are doing 23 | DATABASE_BASELINE=1 24 | 25 | # Server certificates and keys 26 | 27 | # whether to use Let's Encrypt to generate certificates 28 | # if no other certificate is provided, a self-signed certificate will be created 29 | CERT_LETSENCRYPT=false 30 | 31 | # Other parameters 32 | 33 | # Max upload file size 34 | HTTPUPLOAD_MAX_SIZE=20971520 35 | 36 | # HTTP listen port 37 | HTTPUPLOAD_LISTEN_PORT=8828 38 | 39 | # HTTP URLs 40 | HTTPUPLOAD_PUT_URL=https://prime.kontalk.net/media 41 | HTTPUPLOAD_GET_URL=https://prime.kontalk.net/media 42 | 43 | # Backup location 44 | BACKUP_PATH=/mnt/test_backup 45 | -------------------------------------------------------------------------------- /mysql/my.cnf: -------------------------------------------------------------------------------- 1 | [mysqld] 2 | skip_ssl 3 | character-set-server = utf8mb4 4 | collation-server = utf8mb4_general_ci 5 | -------------------------------------------------------------------------------- /tigase/Dockerfile: -------------------------------------------------------------------------------- 1 | # use BRANCH variable to provide source code branch 2 | FROM debian:buster 3 | LABEL "org.kontalk"="Kontalk devteam" 4 | LABEL description="Kontalk server base image" 5 | 6 | # install packages 7 | RUN apt-get -qq update && apt-get -qq -y --no-install-recommends install \ 8 | wget git maven default-mysql-client openssl certbot openjdk-11-jdk make g++ libkyotocabinet16v5 libkyotocabinet-dev gnupg 9 | RUN update-java-alternatives -s java-1.11.0-openjdk-amd64 10 | 11 | # install tools 12 | ENV DOCKERIZE_VERSION v0.6.0 13 | RUN wget https://github.com/jwilder/dockerize/releases/download/$DOCKERIZE_VERSION/dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz \ 14 | && tar -C /usr/local/bin -xzvf dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz \ 15 | && rm dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz 16 | RUN wget https://raw.githubusercontent.com/vishnubob/wait-for-it/master/wait-for-it.sh \ 17 | && mv wait-for-it.sh /usr/local/bin/wait-for-it \ 18 | && chmod +x /usr/local/bin/wait-for-it 19 | 20 | # create kontalk user 21 | RUN useradd --no-log-init -ms /bin/bash kontalk 22 | 23 | # will now work from the kontalk user 24 | USER kontalk 25 | WORKDIR /home/kontalk 26 | # create data directory now so it will have the right owner 27 | RUN mkdir -p data 28 | 29 | # build kontalk server 30 | ENV JAVA_HOME /usr/lib/jvm/java-11-openjdk-amd64 31 | ARG BRANCH 32 | ENV BRANCH ${BRANCH:-master} 33 | RUN wget -qq -O - https://raw.githubusercontent.com/kontalk/tigase-kontalk/${BRANCH}/scripts/installer.sh | bash -s - kontalk-server ${BRANCH} 34 | 35 | # install other requirements (jkyotocabinet) 36 | USER root 37 | COPY install-jkyotocabinet.sh post-install.sh /home/kontalk/ 38 | RUN chown kontalk:kontalk /home/kontalk/install-jkyotocabinet.sh /home/kontalk/post-install.sh 39 | RUN chmod +x /home/kontalk/install-jkyotocabinet.sh /home/kontalk/post-install.sh 40 | RUN ./install-jkyotocabinet.sh 41 | 42 | # post-install operations 43 | USER kontalk 44 | RUN ./post-install.sh 45 | 46 | # copy the entrypoint script 47 | # we don't do this before to take advantage of caching 48 | # when just changing the entrypoint script 49 | USER root 50 | COPY entrypoint.sh /home/kontalk/ 51 | RUN chown kontalk:kontalk /home/kontalk/entrypoint.sh && chmod +x /home/kontalk/entrypoint.sh 52 | 53 | # back to kontalk user and start everything up 54 | USER kontalk 55 | ENTRYPOINT ["/home/kontalk/entrypoint.sh"] 56 | -------------------------------------------------------------------------------- /tigase/README.md: -------------------------------------------------------------------------------- 1 | Kontalk XMPP server image 2 | ========================= 3 | 4 | This is a Docker environment for building a Docker image with a ready-to-use Kontalk server. 5 | 6 | This image can easily be used with a Docker Compose script also found in this repository. 7 | As a matter of fact, this image can't work alone: it needs configuration files and a database container. 8 | 9 | To build this image just run this from a terminal: 10 | 11 | ```shell 12 | docker build -t kontalk/xmppserver --build-arg BRANCH=${BRANCH} . 13 | ``` 14 | 15 | ${BRANCH} should contain the name of the branch of the source code to build. 16 | 17 | You can optionally pass the git branch to use as an argument to the script: 18 | 19 | * master (default) 20 | * staging (mostly stable, used in main Kontalk server) 21 | * production (stable) 22 | 23 | When executed in a container, it will generate server keys automatically for testing purposes. 24 | However, for production environments, it's highly recommended to keep keys exported somewhere else. 25 | 26 | The following environment variables are mandatory: 27 | 28 | * `XMPP_SERVICE`: XMPP service name (not necessarily the container hostname) 29 | * `MYSQL_PASSWORD`: password of the MySQL kontalk account 30 | * `MYSQL_ROOT_PASSWORD`: password for the MySQL root account 31 | * `MYSQL_TIMEZONE`: MySQL timezone 32 | 33 | The following variables will be used if available: 34 | 35 | * `CERT_LETSENCRYPT`: use Let's Encrypt service for generating server certificates (**not implemented yet**) 36 | -------------------------------------------------------------------------------- /tigase/apt_preferences: -------------------------------------------------------------------------------- 1 | Package: * 2 | Pin: release a=stable 3 | Pin-Priority: 700 4 | 5 | Package: * 6 | Pin: release a=testing 7 | Pin-Priority: 650 8 | 9 | Package: * 10 | Pin: release a=unstable 11 | Pin-Priority: 600 12 | -------------------------------------------------------------------------------- /tigase/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | 4 | function urlencode() { 5 | echo -n "$1" | perl -pe 's/([^a-zA-Z0-9_.!~*()'\''-])/sprintf("%%%02X", ord($1))/ge' 6 | } 7 | 8 | # create SSL certificate if needed 9 | SSL_CERT="${HOME}/kontalk-server/certs/${XMPP_SERVICE}.pem" 10 | mkdir -p $(dirname ${SSL_CERT}) 11 | if [ ! -f /tmp/data/privatekey.pem ] || [ ! -f /tmp/data/certificate.pem ]; 12 | then 13 | if [ "${CERT_LETSENCRYPT}" == "true" ]; then 14 | echo "Let's Encrypt certificates are not supported yet." 15 | exit 1 16 | else 17 | echo "Generating SSL certificate" 18 | openssl req -x509 -subj "/C=US/ST=Denial/L=Springfield/O=Dis/CN=${XMPP_SERVICE}" -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365 -nodes 19 | cat cert.pem key.pem >${SSL_CERT} && 20 | rm cert.pem key.pem 21 | fi 22 | else 23 | echo "Using provided SSL certificate" 24 | cat /tmp/data/certificate.pem /tmp/data/privatekey.pem >${SSL_CERT} 25 | [ -f /tmp/data/cachain.pem ] && cat /tmp/data/cachain.pem >>${SSL_CERT} 26 | fi 27 | 28 | # use same certificate for the pubsub domain 29 | cp "${SSL_CERT}" "${HOME}/kontalk-server/certs/pubsub.${XMPP_SERVICE}.pem" 30 | 31 | # create GPG key if needed 32 | if [ ! -f /tmp/data/server-private.key ] || [ ! -f /tmp/data/server-public.key ]; 33 | then 34 | echo "Generating GPG key pair" 35 | KEY_USERID="kontalk-${RANDOM}@${XMPP_SERVICE}" 36 | gpg --batch --gen-key </dev/null 79 | 80 | # create kontalk database objects 81 | cd ${HOME}/kontalk-server/tigase-extension 82 | mvn flyway:baseline \ 83 | -Dflyway.url=jdbc:mysql://db/${MYSQL_DATABASE}?serverTimezone=$(urlencode ${MYSQL_TIMEZONE}) \ 84 | -Dflyway.user=${MYSQL_USER} -Dflyway.password=${MYSQL_PASSWORD} -Dflyway.baselineVersion=${DATABASE_BASELINE} 85 | mvn flyway:migrate \ 86 | -Dflyway.url=jdbc:mysql://db/${MYSQL_DATABASE}?serverTimezone=$(urlencode ${MYSQL_TIMEZONE}) \ 87 | -Dflyway.user=${MYSQL_USER} -Dflyway.password=${MYSQL_PASSWORD} 88 | cd - >/dev/null 89 | 90 | # replace our server entry 91 | mysql -h db --port 3306 -u${MYSQL_USER} -p${MYSQL_PASSWORD} ${MYSQL_DATABASE} <${HOME}/kontalk-server/server-public.key 105 | gpg --export-secret-key ${FINGERPRINT} >${HOME}/kontalk-server/server-private.key 106 | 107 | cd ${HOME}/kontalk-server 108 | exec dockerize \ 109 | -template /tmp/data/init.properties.in:etc/init.properties \ 110 | -wait tcp://db:3306 \ 111 | scripts/tigase.sh run etc/tigase.conf 112 | -------------------------------------------------------------------------------- /tigase/install-jkyotocabinet.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | 4 | yell() { echo "$0: $*" >&2; } 5 | die() { yell "$*"; exit 1; } 6 | try() { "$@" || die "cannot $*"; } 7 | check_for() { which $@ >/dev/null || die "Unable to locate $*"; } 8 | 9 | check_programs() 10 | { 11 | # check for git 12 | check_for git 13 | # check for wget 14 | check_for wget 15 | } 16 | 17 | # check for needed programs 18 | check_programs 19 | 20 | yell "Installing jkyotocabinet" 21 | 22 | try wget "http://fallabs.com/kyotocabinet/javapkg/kyotocabinet-java-1.24.tar.gz" 23 | try tar -xzf kyotocabinet-java-1.24.tar.gz 24 | cd kyotocabinet-java-1.24 25 | try ./configure --prefix=/usr/local 26 | try make 27 | try make install 28 | -------------------------------------------------------------------------------- /tigase/post-install.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | 4 | yell() { echo "$0: $*" >&2; } 5 | 6 | yell "Finishing installation" 7 | 8 | cd kontalk-server/jars 9 | ln -s /usr/local/lib/libjkyotocabinet.so libjkyotocabinet.so 10 | --------------------------------------------------------------------------------